+
-
-
+
-
-
+ class="nav-link"
+ :class="currentTab === 'upload' ? 'active' : ''"
+ @click="currentTab = 'upload'"
+ >
+ Upload
+
-
-
+
-
{{ infoText }}
-
-
+
+ Error: Arweave is used as file storage. Current balance in the Arweave wallet is insufficient to do the upload.
+
+
+ Please send AR tokens to this wallet (min. {{ $config.arweaveMinBalance }} AR): {{ this.$config.arweaveAddress }}.
+
+
+
+
+
+
@@ -51,17 +78,11 @@
-
-
-
@@ -69,61 +90,80 @@
\ No newline at end of file
+
diff --git a/layouts/default.vue b/layouts/default.vue
index 56215d4..2e625b7 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -122,7 +122,7 @@ import NavbarMobile from "~/components/navbars/NavbarMobile.vue";
import SidebarLeft from "~/components/sidebars/SidebarLeft.vue";
import SidebarRight from "~/components/sidebars/SidebarRight.vue";
import ChatSettingsModal from "~/components/ChatSettingsModal.vue";
-import { getActivityPoints } from '~/utils/balanceUtils';
+import { getActivityPoints, getArweaveBalance } from '~/utils/balanceUtils';
import { getAltDomainName, getDomainHolder, getDomainName } from '~/utils/domainUtils';
import { storeAltname, storeReferrer, storeUsername } from '~/utils/storageUtils';
import VerifyAccountOwnership from '~/components/VerifyAccountOwnership.vue';
@@ -193,6 +193,9 @@ export default {
selector: "[data-bs-toggle='popover']",
})
+ // fetch Arweave balance
+ this.fetchArweaveBalance()
+
// check if file upload is enabled
this.siteStore.setFileUploadEnabled(this.$config.fileUploadEnabled);
@@ -255,6 +258,15 @@ export default {
}
},
+ async fetchArweaveBalance() {
+ if (this.$config.arweaveAddress) {
+ const balance = await getArweaveBalance(this.$config.arweaveAddress)
+ //console.log('Arweave balance:', balance)
+
+ this.siteStore.setArweaveBalance(balance)
+ }
+ },
+
async fetchChatTokenBalance() {
if (this.$config.chatTokenAddress) {
const chatTokenInterface = new ethers.utils.Interface([
diff --git a/nuxt.config.ts b/nuxt.config.ts
index 7b7f3cd..28f76a9 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -54,7 +54,9 @@ export default defineNuxtConfig({
airdropApAddress: "", // chat token claim for APs
airdropClaimDomainsAddress: "", // chat token claim for domain holders
altDomain: ".mode", // alternative domain (e.g. .eth, .crypto, etc.)
+ arweaveAddress: process.env.ARWEAVE_ADDRESS,
arweaveGateway: 'https://arweave.net/',
+ arweaveMinBalance: 0.02, // minimum AR balance to upload files
blockExplorerBaseUrl: "https://explorer.mode.network", // no trailing slash!
chatChannels: { // go to Orbis Dashboard (https://useorbis.com/dashboard), create a new Project and then create a new Context for each of the channels below
"general": "kjzl6cwe1jw149v2ugvw3kux2bllw3bka0vl2rzgmdkaceg3srm62nww7iuvkwi", // general discussion channel
@@ -72,6 +74,7 @@ export default defineNuxtConfig({
favicon: "/img/favicon.svg",
fileUploadEnabled: true, // enable/disable file uploads (enable only if external file storage is used, e.g. Arweave)
fileUploadSizeLimit: 1 * 1024 * 1024, // max file upload size in bytes (1 * 1024 * 1024 = 1 MB)
+ fileUploadStorageType: "arweave", // "imagekit" or "arweave" (or leave empty for no file uploads)
fileUploadTokenService: process.env.FILE_UPLOAD_SERVICE || "netlify", // "netlify" or "vercel" (or leave empty for no file uploads)
getPostsLimit: 30, // number of posts to fetch from Orbis in the getPosts() function
governanceUrl: "", // governance url (snapshot, Tally, etc.)
diff --git a/pages/nft/create.vue b/pages/nft/create.vue
index f4253fc..deed6ef 100644
--- a/pages/nft/create.vue
+++ b/pages/nft/create.vue
@@ -160,7 +160,7 @@
@processFileUrl="insertImage"
title="Upload your NFT image"
infoText="Upload the NFT image."
- storageType="arweave"
+ :storageType="$config.fileUploadStorageType"
:componentId="$.uid"
:maxFileSize="$config.fileUploadSizeLimit"
/>
diff --git a/store/site.ts b/store/site.ts
index f32bfdd..6258462 100644
--- a/store/site.ts
+++ b/store/site.ts
@@ -6,83 +6,92 @@ export const useSiteStore = defineStore({
state: () => {
return {
- colorMode: "dark",
+ arweaveBalance: 0,
+ colorMode: 'dark',
fileUploadEnabled: true,
- showOnlyMasterPosts: useLocalStorage('showOnlyMasterPosts', "false"),
- slippage: "0.5", // percentage (%)
- swapDeadline: "20" // minutes
+ showOnlyMasterPosts: useLocalStorage('showOnlyMasterPosts', 'false'),
+ slippage: '0.5', // percentage (%)
+ swapDeadline: '20', // minutes
}
},
getters: {
+ getArweaveBalance(state) {
+ return state.arweaveBalance
+ },
+
getColorMode(state) {
- const pStorage = useLocalStorage('colorMode', null);
+ const pStorage = useLocalStorage('colorMode', null)
if (pStorage.value) {
- state.colorMode = pStorage.value;
+ state.colorMode = pStorage.value
}
- return state.colorMode;
+ return state.colorMode
},
getFileUploadEnabled(state) {
- return state.fileUploadEnabled;
+ return state.fileUploadEnabled
},
getShowOnlyMasterPosts(state) {
- const pStorage = useLocalStorage('showOnlyMasterPosts', null);
+ const pStorage = useLocalStorage('showOnlyMasterPosts', null)
if (pStorage.value) {
- state.showOnlyMasterPosts = pStorage.value;
+ state.showOnlyMasterPosts = pStorage.value
}
- return state.showOnlyMasterPosts;
+ return state.showOnlyMasterPosts
},
getSlippage(state) {
- const pStorage = useLocalStorage('swapSlippage', "0.5");
+ const pStorage = useLocalStorage('swapSlippage', '0.5')
if (pStorage.value) {
- state.slippage = pStorage.value;
+ state.slippage = pStorage.value
}
- return state.slippage;
+ return state.slippage
},
getSwapDeadline(state) {
- const pStorage = useLocalStorage('swapDeadline', "20");
+ const pStorage = useLocalStorage('swapDeadline', '20')
if (pStorage.value) {
- state.swapDeadline = pStorage.value;
+ state.swapDeadline = pStorage.value
}
- return state.swapDeadline;
- }
+ return state.swapDeadline
+ },
},
actions: {
+ setArweaveBalance(balance: number) {
+ this.arweaveBalance = balance
+ },
+
setColorMode(cm: string) {
- this.colorMode = cm;
- localStorage.setItem("colorMode", cm);
+ this.colorMode = cm
+ localStorage.setItem('colorMode', cm)
},
setFileUploadEnabled(enabled: boolean) {
- this.fileUploadEnabled = enabled;
+ this.fileUploadEnabled = enabled
},
setShowOnlyMasterPosts(somp: string) {
- this.showOnlyMasterPosts = somp;
- localStorage.setItem("showOnlyMasterPosts", somp);
+ this.showOnlyMasterPosts = somp
+ localStorage.setItem('showOnlyMasterPosts', somp)
},
setSlippage(slippage: string) {
- this.slippage = slippage;
- localStorage.setItem("swapSlippage", slippage);
+ this.slippage = slippage
+ localStorage.setItem('swapSlippage', slippage)
},
setSwapDeadline(swapDeadline: string) {
- this.swapDeadline = swapDeadline;
- localStorage.setItem("swapDeadline", swapDeadline);
- }
- }
-})
\ No newline at end of file
+ this.swapDeadline = swapDeadline
+ localStorage.setItem('swapDeadline', swapDeadline)
+ },
+ },
+})
diff --git a/utils/balanceUtils.js b/utils/balanceUtils.js
index bdd6062..0b430fe 100644
--- a/utils/balanceUtils.js
+++ b/utils/balanceUtils.js
@@ -1,70 +1,67 @@
-import { ethers } from "ethers";
-import Erc20Abi from "~/assets/abi/Erc20Abi.json";
+import Arweave from 'arweave'
+import { ethers } from 'ethers'
+import Erc20Abi from '~/assets/abi/Erc20Abi.json'
+
+// Initialize Arweave
+const arweave = Arweave.init({
+ host: 'arweave.net',
+ port: 443,
+ protocol: 'https'
+})
export async function getActivityPoints(userAddress, signer) {
- const config = useRuntimeConfig();
-
- let provider = signer;
+ const config = useRuntimeConfig()
- if (!signer) {
- provider = this.$getFallbackProvider(config.supportedChainId);
- }
+ let provider = signer
const activityPointsInterface = new ethers.utils.Interface([
- "function getPoints(address user_) external view returns (uint256)",
- ]);
+ 'function getPoints(address user_) external view returns (uint256)',
+ ])
- const activityPointsContract = new ethers.Contract(config.activityPointsAddress, activityPointsInterface, provider);
+ const activityPointsContract = new ethers.Contract(config.activityPointsAddress, activityPointsInterface, provider)
- const pointsWei = await activityPointsContract.getPoints(userAddress);
+ const pointsWei = await activityPointsContract.getPoints(userAddress)
- let activityPoints = Number(ethers.utils.formatEther(pointsWei));
+ let activityPoints = Number(ethers.utils.formatEther(pointsWei))
if (activityPoints < 1) {
- activityPoints = activityPoints.toFixed(2);
+ activityPoints = activityPoints.toFixed(2)
} else {
- activityPoints = Math.round(activityPoints);
+ activityPoints = Math.round(activityPoints)
}
- return activityPoints;
+ return activityPoints
}
-export async function getTokenAllowance(token, userAddress, beneficiary, signer) {
- const config = useRuntimeConfig();
-
- let provider = signer;
+export async function getArweaveBalance(arweaveAddress) {
+ const balance = await arweave.wallets.getBalance(arweaveAddress)
+ return arweave.ar.winstonToAr(balance)
+}
- if (!provider) {
- provider = this.$getFallbackProvider(config.supportedChainId);
- }
+export async function getTokenAllowance(token, userAddress, beneficiary, signer) {
+ let provider = signer
- const contract = new ethers.Contract(token.address, Erc20Abi, provider);
- const allowanceWei = await contract.allowance(userAddress, beneficiary);
+ const contract = new ethers.Contract(token.address, Erc20Abi, provider)
+ const allowanceWei = await contract.allowance(userAddress, beneficiary)
- return ethers.utils.formatUnits(allowanceWei, token.decimals);
+ return ethers.utils.formatUnits(allowanceWei, token.decimals)
}
export async function getTokenBalance(token, userAddress, signer) {
- const config = useRuntimeConfig();
-
- let provider = signer;
-
- if (!provider) {
- provider = this.$getFallbackProvider(config.supportedChainId);
- }
+ let provider = signer
- let balanceWei;
+ let balanceWei
if (token.address === ethers.constants.AddressZero) {
if (!signer) {
- balanceWei = await provider.getBalance(userAddress);
+ balanceWei = await provider.getBalance(userAddress)
} else {
- balanceWei = await signer.getBalance();
+ balanceWei = await signer.getBalance()
}
} else {
- const contract = new ethers.Contract(token.address, Erc20Abi, provider);
- balanceWei = await contract.balanceOf(userAddress);
+ const contract = new ethers.Contract(token.address, Erc20Abi, provider)
+ balanceWei = await contract.balanceOf(userAddress)
}
- return ethers.utils.formatUnits(balanceWei, token.decimals);
-}
\ No newline at end of file
+ return ethers.utils.formatUnits(balanceWei, token.decimals)
+}
diff --git a/utils/textUtils.js b/utils/textUtils.js
index 4a1a65b..676e0fe 100644
--- a/utils/textUtils.js
+++ b/utils/textUtils.js
@@ -1,6 +1,3 @@
-//import { isBlank, zeroWidthCharacters } from 'printable-characters';
-import { getWorkingUrl } from '~/utils/ipfsUtils'
-
export function findFirstCollectionUrl(text) {
// if there is an NFT collection url (from our website) in the text, return it as address string
// example:
@@ -13,12 +10,12 @@ export function findFirstCollectionUrl(text) {
try {
urlRegex = new RegExp(
- '(https?:\\/\\/(?!.*\\.(jpg|png|jpeg|img|gif|webp|pdf|docx))[^\\s]+)(?