Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(upload folder): turbo upload folder MVP PE-4643 #15

Merged
merged 10 commits into from
Oct 3, 2024
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v20.12.2
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "turbo-app",
"version": "1.0.0",
"version": "1.1.0",
"type": "module",
"description": "ArDrive Turbo App",
"homepage": "./",
Expand All @@ -19,7 +19,9 @@
"test": "echo \"TODO: add tests\" && exit 0"
},
"dependencies": {
"@ardrive/turbo-sdk": "latest",
"@ardrive/turbo-sdk": "1.19.0",
"@solana/web3.js": "^1.95.3",
"ethers": "^6.13.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.20.1"
Expand Down
2 changes: 2 additions & 0 deletions src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { GiftPage } from "./pages/GiftPage";
import { RedeemPage } from "./pages/RedeemPage";
import { FiatTopUpPage } from "./pages/FiatTopUpPage";
import { CryptoTopUpPage } from "./pages/CryptoTopUpPage";
import { UploadPage } from "./pages/UploadPage";

export function Router() {
return (
Expand All @@ -13,6 +14,7 @@ export function Router() {
<Route path="/top-up" element={<FiatTopUpPage />} />
<Route path="/top-up/fiat" element={<FiatTopUpPage />} />
<Route path="/top-up/crypto" element={<CryptoTopUpPage />} />
<Route path="/upload" element={<UploadPage />} />

<Route
path="/"
Expand Down
75 changes: 75 additions & 0 deletions src/components/TurboWalletConnector.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
.wallet-connector {
padding: 0rem 1.5rem 1.5rem 1.5rem;
}

.wallet-info {
font-family: Wavehaus-Bold;
font-size: 1rem;
color: var(--white);
background-color: var(--off-gray);
padding: 1.5rem;
border-radius: 8px;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}

.wallet-info .wallet-type {
font-size: 0.9rem;
font-weight: bold;
color: var(--ardrive-red);
margin-right: 0.5rem;
}

.wallet-info .wallet-address {
font-family: Wavehaus-Bold; /* Optional: to give the address a monospaced look */
font-size: 1.1rem;
color: var(--text-white);
margin-right: 1rem;
}

.wallet-connector-buttons {
display: flex;
flex-direction: row;
justify-content: center;
gap: 1rem;
width: 100%;
}

.wallet-connector button {
background-color: var(--ardrive-red);
color: var(--white);
padding: 0.75rem 1.25rem;
border: none;
border-radius: 0.5rem;
cursor: pointer;
font-family: Wavehaus-Bold;
width: auto;
}

.wallet-connector button:hover {
background-color: var(--ardrive-red);
filter: brightness(0.9);
}

.wallet-connector button:disabled {
background-color: var(--light-gray);
cursor: not-allowed;
}

.wallet-info button {
font-size: 0.6rem;
background-color: var(--light-gray);
color: var(--black);
border: none;
padding: 0.25rem 0.75rem;
border-radius: 0.25rem;
cursor: pointer;
margin-left: auto; /* Push the button to the right */
}

.wallet-info button:hover {
background-color: var(--ardrive-red);
color: var(--white);
}
136 changes: 136 additions & 0 deletions src/components/TurboWalletConnector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import {
TurboAuthenticatedClient,
TurboFactory,
SolanaWalletAdapter,
ArconnectSigner,
} from "@ardrive/turbo-sdk/web";
import { PublicKey } from "@solana/web3.js";
import { ethers } from "ethers";
import { useState } from "react";
import { turboConfig } from "../constants";
import { getArconnect } from "../utils/arconnect";
import "./TurboWalletConnector.css";

interface TurboWalletConnectorProps {
setTurbo: (turbo: TurboAuthenticatedClient | undefined) => void;
}

export default function TurboWalletConnector({
setTurbo,
}: TurboWalletConnectorProps): JSX.Element {
const [currentToken, setCurrentToken] = useState<string | undefined>(
undefined,
);
const [walletAddress, setWalletAddress] = useState<string | undefined>(
undefined,
);

const setupTurbo = async (turbo: TurboAuthenticatedClient) => {
setWalletAddress(await turbo.signer.getNativeAddress());
setTurbo(turbo);
};

const disconnectWallet = () => {
setTurbo(undefined);
setCurrentToken(undefined);
setWalletAddress(undefined);
};

const connectEthWallet = async () => {
try {
// Check if MetaMask is installed

if (window.ethereum) {
// Find the MetaMask provider in the list
const metaMaskProvider = window.ethereum.providers?.find(
(provider) => provider.isMetaMask,
);

const provider = new ethers.BrowserProvider(
metaMaskProvider ?? window.ethereum,
); // Use the MetaMask provider
const signer = await provider.getSigner();

await setupTurbo(
TurboFactory.authenticated({
token: "ethereum",
walletAdapter: {
getSigner: () => signer,
},
}),
);

setCurrentToken("ethereum");
}
} catch (err) {
console.error(err);
}
};

const connectSolWallet = async () => {
try {
// Check if Phantom is installed
if (window.solana) {
const provider = window.solana;

const publicKey = new PublicKey((await provider.connect()).publicKey);

const wallet: SolanaWalletAdapter = {
publicKey,
signMessage: async (message: Uint8Array) => {
// Call Phantom's signMessage method
const { signature } = await provider.signMessage(message);

return signature;
},
};

await setupTurbo(
TurboFactory.authenticated({
token: "solana",
walletAdapter: wallet,
}),
);
setCurrentToken("solana");
}
} catch (err) {
console.error(err);
}
};

const connectArWallet = async () => {
try {
await getArconnect();
const arconnect_signer = new ArconnectSigner(window.arweaveWallet);

await setupTurbo(
TurboFactory.authenticated({
token: "arweave",
signer: arconnect_signer,
...turboConfig,
}),
);
setCurrentToken("arweave");
} catch (err) {
console.error(err);
}
};
return (
<div className="form wallet-connector">
<h3>{currentToken ? "Current" : "Connect"} Wallet</h3>
{walletAddress && currentToken ? (
<p className="wallet-info">
<span className="wallet-type">{currentToken}</span>{" "}
<span className="wallet-address">{walletAddress}</span>
<button onClick={disconnectWallet}>Disconnect</button>
</p>
) : (
<div className="wallet-connector-buttons">
<button onClick={connectEthWallet}>Connect Ethereum Wallet</button>
<button onClick={connectSolWallet}>Connect Solana Wallet</button>
<button onClick={connectArWallet}>Connect Arweave Wallet</button>
</div>
)}
</div>
);
}
2 changes: 1 addition & 1 deletion src/hooks/useCreditsForFiat.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TurboFactory, USD } from "@ardrive/turbo-sdk";
import { TurboFactory, USD } from "@ardrive/turbo-sdk/web";
import { useState, useRef, useEffect } from "react";
import { turboConfig, wincPerCredit } from "../constants";

Expand Down
32 changes: 32 additions & 0 deletions src/hooks/useCreditsForToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { TurboFactory } from "@ardrive/turbo-sdk/web";
import { useState, useRef, useEffect } from "react";
import { turboConfig, wincPerCredit } from "../constants";

export function useCreditsForToken(
debouncedTokenAmount: string,
errorCallback: (message: string) => void,
): [string | undefined, string | undefined] {
const [winc, setWinc] = useState<string | undefined>(undefined);
const usdWhenCreditsWereLastUpdatedRef = useRef<string | undefined>(
undefined,
);

// Get credits for USD amount when USD amount has stopped debouncing
useEffect(() => {
TurboFactory.unauthenticated(turboConfig)
.getWincForToken({ tokenAmount: debouncedTokenAmount })
.then(({ winc }) => {
usdWhenCreditsWereLastUpdatedRef.current = debouncedTokenAmount;
setWinc(winc);
})
.catch((err) => {
console.error(err);
errorCallback(`Error getting credits for USD amount: ${err.message}`);
});
}, [debouncedTokenAmount, errorCallback]);

return [
winc ? (+winc / wincPerCredit).toString() : undefined,
usdWhenCreditsWereLastUpdatedRef.current,
];
}
2 changes: 1 addition & 1 deletion src/hooks/useWincForOneGiB.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TurboFactory } from "@ardrive/turbo-sdk";
import { TurboFactory } from "@ardrive/turbo-sdk/web";
import { useState, useEffect } from "react";
import { turboConfig } from "../constants";

Expand Down
3 changes: 2 additions & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ input[type="number"] {
color: var(--ardrive-red);
}

h1 {
h1,
h3 {
font-family: Wavehaus-Extra;
}

Expand Down
2 changes: 1 addition & 1 deletion src/pages/CryptoTopUpPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
TurboFactory,
ARToTokenAmount,
ArconnectSigner,
} from "@ardrive/turbo-sdk";
} from "@ardrive/turbo-sdk/web";
import { getArconnect } from "../utils/arconnect";
import { NewToArDriveInfo } from "../components/NewToArDriveInfo";
import { useWincForOneGiB } from "../hooks/useWincForOneGiB";
Expand Down
2 changes: 1 addition & 1 deletion src/pages/FiatTopUpPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "../constants";
import { Page } from "./Page";
import { useLocation } from "react-router-dom";
import { TurboFactory, USD } from "@ardrive/turbo-sdk";
import { TurboFactory, USD } from "@ardrive/turbo-sdk/web";
import { NewToArDriveInfo } from "../components/NewToArDriveInfo";
import { getArconnect } from "../utils/arconnect";
import { useCreditsForFiat } from "../hooks/useCreditsForFiat";
Expand Down
Loading
Loading