Irys in the browser
Working with Irys in the browser is similar to working with our server-side SDK, however there are a few differences which are demonstrated below.
The Irys L1 private testnet is now live. Migrate your project (opens in a new tab) in 5 minutes and take advantage of our latest features.
Installing
Install using npm:
npm install @irys/sdk
or yarn:
yarn add @irys/sdk
If you're using Irys with React and npx create-react-app
, you will need to follow some extra setup
steps.
Importing
import { WebIrys } from "@irys/sdk";
Connecting to a node
When instantiating a WebIrys
object pass:
network
: Usemainnet
.token
: Payment tokenwallet
: A wallet object containing the end-user's injected provider and the name of the provider package your project uses
const getWebIrys = async () => {
// Ethers5 provider
await window.ethereum.enable();
const provider = new providers.Web3Provider(window.ethereum);
const network = "mainnet";
const token = "ethereum";
// Optional RPC URLs
const rpcUrl = "";
// Create a wallet object
const wallet = { rpcUrl: rpcUrl, name: "ethersv5", provider: provider };
// Use the wallet object
const webIrys = new WebIrys({ network, token, wallet });
await webIrys.ready();
return webIrys;
};
After instantiating the object, call webIrys.ready()
.
Supported providers
WebIrys supports the following providers. When instantiating a new WebIrys
object, you must pass in the name of the provider you will be using.
Package | Parameter value |
---|---|
Ethers 5 (opens in a new tab) | ethersv5 |
Ethers 6 (opens in a new tab) | ethersv6 |
Solana (opens in a new tab) | solana |
Viem v2 (opens in a new tab) | viemv2 |
Aptos
const aptosWallet = useWallet();
const getWebIrys = async () => {
const network = "mainnet";
const token = "aptos";
const rpcUrl = "testnet"; // "mainnet" || "testnet"
const wallet = { rpcUrl: rpcUrl, name: "aptos", provider: aptosWallet };
const webIrys = new WebIrys({ network, token, wallet });
await webIrys.ready();
return webIrys;
};
Solana React Hooks
When working with the Solana React hooks, start by wrapping your components in the Solana ConnectionProvider
WalletProvider
and WalletModalProvider
providers.
import { ConnectionProvider, WalletProvider } from "@solana/wallet-adapter-react";
import { WalletModalProvider } from "@solana/wallet-adapter-react-ui";
import { PhantomWalletAdapter } from "@solana/wallet-adapter-wallets";
const network = WalletAdapterNetwork.Mainnet;
const endpoint = useMemo(() => clusterApiUrl(network), [network]);
const wallets = useMemo(() => [new PhantomWalletAdapter()], [network]);
<ConnectionProvider endpoint={endpoint}>
<WalletProvider wallets={wallets} autoConnect>
<WalletModalProvider>
<YourComponents />
</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>;
Then, in components where you need to access a WebIrys
object use the useWallet()
hook to get a reference to the user's injected provider, and pass that into WebIrys
when instantiating a new object.
import { useWallet } from "@solana/wallet-adapter-react";
const wallet = useWallet();
const getIrys = async (): Promise<WebIrys> => {
// Optional RPC URL
const rpcUrl = "";
const wallet = { rpcUrl: rpcUrl, name: "solana", provider: wallet };
const webIrys = new WebIrys({ network: "mainnet", token: "solana", wallet });
await webIrys.ready();
return webIrys;
};
Additional providers
Additionally, the following providers will work with extra setup code.
Package | Parameter value |
---|---|
Othent | othent |
Privy | privy |
Othent (opens in a new tab)
export const getWebIrys = async () => {
const wallet = { name: "Othent KMS", provider: othentKMS };
const network = "mainnet";
const token = "arweave";
const webIrys = new WebIrys({ network, token, wallet });
await webIrys.ready();
return webIrys;
};
Privy (opens in a new tab)
Initialize the Privy provider with your app ID and wrap it around your components. In most NextJS projects, you will place this code in your app.tsx
file. In our example, we use the <PrivyIrys />
component as a placeholder for your app's top-level component structure.
We also have a demo repository (opens in a new tab) teaching how to build a PWA photo-sharing app using Privy and Irys.
import { PrivyProvider } from "@privy-io/react-auth";
<PrivyProvider
appId="YOUR-APP-ID"
onSuccess={handlePrivyLogin}
config={{
loginMethods: ["email", "wallet"],
appearance: {
theme: "dark",
accentColor: "#676FFF",
logo: "https://docs.irys.xyz/img/favicon.svg",
},
embeddedWallets: {
createOnLogin: "users-without-wallets",
},
}}
>
<PrivyIrys />
</PrivyProvider>;
Then, write code to login with Privy and create a new WebIrys
object.
The code to create a WebIrys
object differs depending on if you're using an external wallet (opens in a new tab) vs an embedded one (opens in a new tab). When using external wallets, pass the Ethers provider returned from the Wallet
object, when using embedded wallets pass the sendTransaction
Privy React hook.
The following code uses conditional logic to create the correct WebIrys
object based on the wallet type. If your application only supports a single wallet type, feel free to simplify the code.
import { User, usePrivy, useWallets } from "@privy-io/react-auth";
const { wallets } = useWallets();
const { login } = usePrivy();
const { sendTransaction } = usePrivy();
// First login
login();
// The 0th position wallet is the most recently used one
const w = wallets.at(0);
// Or find the embedded wallet
// const w = wallets.find((wallet) => wallet.walletClientType === 'privy');
// Then create a WebIrys object
const getWebIrys = async () => {
const network = "mainnet";
const token = "ethereum";
const provider = await w?.getEthersProvider();
if (!provider) throw new Error(`Cannot find privy wallet`);
const irysWallet =
w?.walletClientType === "privy"
? { name: "privy-embedded", provider, sendTransaction }
: { name: "privy", provider };
const webIrys = new WebIrys({
network,
token,
wallet: irysWallet,
});
await webIrys.ready();
};
Funding a node
Fund a node using any of our supported tokens:
const fundNode = async () => {
const webIrys = await getWebIrys();
try {
const fundTx = await webIrys.fund(webIrys.utils.toAtomic(0.05));
console.log(`Successfully funded ${webIrys.utils.fromAtomic(fundTx.quantity)} ${webIrys.token}`);
} catch (e) {
console.log("Error uploading data ", e);
}
};
Uploading
Data uploaded to Irys is given a millisecond-accurate timestamp, attributes and authorship details before being passed to Arweave for permanent storage. This information is used to create a signed receipt that can be trustlessly verified.
Uploading data
const uploadData = async () => {
const webIrys = await getWebIrys();
const dataToUpload = "GM world.";
try {
const receipt = await webIrys.upload(dataToUpload);
console.log(`Data uploaded ==> https://gateway.irys.xyz/${receipt.id}`);
} catch (e) {
console.log("Error uploading data ", e);
}
};
Uploading a file
Upload a File (opens in a new tab) object.
const uploadFile = async (fileToUpload: File) => {
const webIrys = await getWebIrys();
// Your file
const tags = [{ name: "application-id", value: "MyNFTDrop" }];
try {
const receipt = await webIrys.uploadFile(fileToUpload, { tags: tags });
console.log(`File uploaded ==> https://gateway.irys.xyz/${receipt.id}`);
} catch (e) {
console.log("Error uploading file ", e);
}
};
Uploading a folder
Upload an array of File (opens in a new tab) objects.
Upon upload, a manifest is automatically created. Your files can be accessed https://gateway.irys.xyz/[manifestId]/[file-name]
.
const uploadFolder = async (files: File[], tags: Tag[]) => {
const webIrys = await getIrys();
try {
const receipt = await webIrys.uploadFolder(files, {
tags,
}); //returns the manifest ID
console.log(`Files uploaded. Manifest Id=${receipt.manifestId} Receipt Id=${receipt.id}`);
} catch (e) {
console.log("Error uploading file ", e);
}
};