This SDK provides a set of libraries designed as foundational building blocks for developers to create and interact with applications on Arweave's permaweb. These libraries aim to contribute building on the composable web, promoting interoperability and reusability across decentralized applications. With libraries for managing profiles, atomic assets, collections, and more, this SDK simplifies the development of decentralized, permanent applications.
- Prerequisites
- Installation
- Initialization
- Usage
- Examples
- Resources
node >= v18.0
npm
oryarn
arweave
@permaweb/aoconnect
If arweave
or @permaweb/aoconnect
is not already installed, add them to the installation command below as additional packages
npm install @permaweb/libs
or
yarn add @permaweb/libs
import Arweave from "arweave";
import { connect, createDataItemSigner } from "@permaweb/aoconnect";
import Permaweb from "@permaweb/libs";
// Browser Usage
const wallet = window.arweaveWallet;
// NodeJS Usage
const wallet = JSON.parse(readFileSync(process.env.PATH_TO_WALLET, "utf-8"));
const permaweb = Permaweb.init({
ao: connect(),
arweave: Arweave.init(),
signer: createDataItemSigner(wallet),
});
Zones are representations of entities on the permaweb that contain relevant information and can perform actions on the entity's behalf. A profile is an instance of a zone with specific metadata (Read the spec).
const zoneId = await permaweb.createZone();
Parameters
tags (optional)
: Additional tags
Response
ZoneProcessId;
const zoneUpdateId = await permaweb.updateZone({
name: "Sample Zone",
metadata: {
description: "A sample zone for testing",
version: "1.0.0",
},
}, zoneId
);
Parameters
args
: Zone data to update, specified in an objectzoneId
: The ID of the zone to update
Response
ZoneUpdateId;
const zone = await permaweb.getZone(zoneId);
Parameters
zoneId
: The ID of the zone to fetch
Response
{ store: [], assets: [] };
Profiles are a digital representation of entities, such as users, organizations, or channels. They instantiate zones with specific metadata that describes the entity and can be associated with various digital assets and collections. Profiles are created, updated, and fetched using the following functions.
const profileId = await permaweb.createProfile({
username: "Sample Zone",
displayName: "Sample Zone",
description: "Sample description",
thumbnail: "Thumbnail image data",
banner: "Banner image data",
});
Parameters
args
: Object containing profile details, includingusername
,displayName
,description
,thumbnail
, andbanner
callback (optional)
: Callback function for client use
Response
ProfileProcessId;
const profileId = await permaweb.updateProfile({
username: "Sample Zone",
displayName: "Sample Zone",
description: "Sample description",
thumbnail: "Thumbnail image data",
banner: "Banner image data",
}, profileId
);
Parameters
args
: Profile details to update, structured similarly tocreateProfile
profileId
: The ID of the profile to updatecallback (optional)
: Callback function for client use
Response
ProfileProcessUpdateId;
const profile = await permaweb.getProfileById(profileId);
Parameters
profileId
: The ID of the profile to fetch
Response
{
id: "ProfileProcessId",
walletAddress: "WalletAddress",
username: "Sample username",
displayName: "Sample display name",
description: "Sample description",
thumbnail: "ThumbnailTxId",
banner: "BannerTxId",
assets: [
{ id: "AssetProcessId1", quantity: "1", dateCreated: 123456789, lastUpdate: 123456789 },
{ id: "AssetProcessId2", quantity: "1", dateCreated: 123456789, lastUpdate: 123456789 },
{ id: "AssetProcessId3", quantity: "1", dateCreated: 123456789, lastUpdate: 123456789 },
]
}
const profile = await permaweb.getProfileByWalletAddress(walletAddress);
Parameters
walletAddress
: The wallet address associated with the profile
Response
{
id: "ProfileProcessId",
walletAddress: "WalletAddress",
username: "Sample username",
displayName: "Sample display name",
description: "Sample description",
thumbnail: "ThumbnailTxId",
banner: "BannerTxId",
assets: [
{ id: "AssetProcessId1", quantity: "1", dateCreated: 123456789, lastUpdate: 123456789 },
{ id: "AssetProcessId2", quantity: "1", dateCreated: 123456789, lastUpdate: 123456789 },
{ id: "AssetProcessId3", quantity: "1", dateCreated: 123456789, lastUpdate: 123456789 },
]
}
Atomic assets are unique digital item consisting of an AO process and its associated data which are stored together in a single transaction on Arweave (Read the spec).
const assetId = await permaweb.createAtomicAsset({
title: 'Example Title',
description, 'Example Description',
type: 'Example Atomic Asset Type',
topics: ['Topic 1', 'Topic 2', 'Topic 3'],
contentType: 'text/html',
data: '1234'
});
Parameters
args
: Object containing profile details, includingtitle
,description
,type
,topics
,contentType
, anddata
callback (optional)
: Callback function for client use
Response
AssetProcessId;
const asset = await permaweb.getAtomicAsset(assetId);
Parameters
assetId
: The ID of the asset to fetch
Response
{
id: 'z0f2O9Fs3yb_EMXtPPwKeb2O0WueIG5r7JLs5UxsA4I',
title: 'City',
description: 'A collection of AI generated images of different settings and areas',
type: null,
topics: null,
contentType: 'image/png',
renderWith: null,
thumbnail: null,
udl: {
access: { value: 'One-Time-0.1' },
derivations: { value: 'Allowed-With-One-Time-Fee-0.1' },
commercialUse: { value: 'Allowed-With-One-Time-Fee-0.1' },
dataModelTraining: { value: 'Disallowed' },
paymentMode: 'Single',
paymentAddress: 'uf_FqRvLqjnFMc8ZzGkF4qWKuNmUIQcYP0tPlCGORQk',
currency: 'xU9zFkq3X2ZQ6olwNVvr1vUWIjc3kXTWr7xKQD6dh10'
},
creator: 'SaXnsUgxJLkJRghWQOUs9-wB0npVviewTkUbh2Yk64M',
collectionId: 'XcfPzHzxt2H8FC03MAC_78U1YwO9Gdk72spbq70NuNc',
implementation: 'ANS-110',
dateCreated: 1717663091000,
blockHeight: 1439467,
ticker: 'ATOMIC',
denomination: '1',
balances: {
'SaXnsUgxJLkJRghWQOUs9-wB0npVviewTkUbh2Yk64M': '1',
cfQOZc7saMMizHtBKkBoF_QuH5ri0Bmb5KSf_kxQsZE: '1',
U3TjJAZWJjlWBB4KAXSHKzuky81jtyh0zqH8rUL4Wd0: '98'
},
transferable: true,
tags: [{ name: 'Remaining', value: 'Tag' }]
}
const assets = await permaweb.getAtomicAssets(assetIds);
Parameters
assetIds
: A list of the asset IDs to fetch
Response
[
{
id: "AssetProcessId1",
title: "City",
description:
"A collection of AI generated images of different settings and areas",
type: null,
topics: null,
contentType: "image/png",
renderWith: null,
thumbnail: null,
udl: {
access: { value: "One-Time-0.1" },
derivations: { value: "Allowed-With-One-Time-Fee-0.1" },
commercialUse: { value: "Allowed-With-One-Time-Fee-0.1" },
dataModelTraining: { value: "Disallowed" },
paymentMode: "Single",
paymentAddress: "uf_FqRvLqjnFMc8ZzGkF4qWKuNmUIQcYP0tPlCGORQk",
currency: "xU9zFkq3X2ZQ6olwNVvr1vUWIjc3kXTWr7xKQD6dh10",
},
creator: "SaXnsUgxJLkJRghWQOUs9-wB0npVviewTkUbh2Yk64M",
collectionId: "XcfPzHzxt2H8FC03MAC_78U1YwO9Gdk72spbq70NuNc",
implementation: "ANS-110",
dateCreated: 1717663091000,
blockHeight: 1439467,
tags: [{ name: "Remaining", value: "Tag" }],
},
{
id: "AssetProcessId2",
title: "City",
description:
"A collection of AI generated images of different settings and areas",
type: null,
topics: null,
contentType: "image/png",
renderWith: null,
thumbnail: null,
udl: {
access: { value: "One-Time-0.1" },
derivations: { value: "Allowed-With-One-Time-Fee-0.1" },
commercialUse: { value: "Allowed-With-One-Time-Fee-0.1" },
dataModelTraining: { value: "Disallowed" },
paymentMode: "Single",
paymentAddress: "uf_FqRvLqjnFMc8ZzGkF4qWKuNmUIQcYP0tPlCGORQk",
currency: "xU9zFkq3X2ZQ6olwNVvr1vUWIjc3kXTWr7xKQD6dh10",
},
creator: "SaXnsUgxJLkJRghWQOUs9-wB0npVviewTkUbh2Yk64M",
collectionId: "XcfPzHzxt2H8FC03MAC_78U1YwO9Gdk72spbq70NuNc",
implementation: "ANS-110",
dateCreated: 1717663091000,
blockHeight: 1439467,
tags: [{ name: "Remaining", value: "Tag" }],
},
];
Comments are an instantiation of atomic assets created with additional tags to link them with other comments / atomic assets with specific data or root contexts.
const commentId = await permaweb.createComment({
content: "Sample comment on an atomic asset",
creator: profileId,
parentId: atomicAssetId,
});
Parameters
args
: Object containingcontent
,creator
,parentId
, androotId (optional)
callback (optional)
: Callback function for status updates.
Response
CommentProcessId;
const comment = await permaweb.getComment(commentId);
Parameters
commentId
: The ID of the comment to fetch.
Response
{
id: 'CommentProcessId',
title: 'Comment Title',
description: 'Comment Description',
dataSource: 'Data Source Identifier',
rootSource: 'Root Source Identifier',
contentType: 'text/plain',
data: 'Comment data',
creator: 'Creator Identifier',
collectionId: 'Collection Identifier',
transferable: true,
tags: [
{ name: 'Data-Source', value: 'Data Source Identifier' },
{ name: 'Root-Source', value: 'Root Source Identifier' }
]
}
const comments = await permaweb.getComments({
parentId: atomicAssetId,
});
Parameters
args
: Object containingparentId
orrootId
Response
[
{
id: "CommentProcessId1",
title: "Comment Title 1",
description: "Comment Description 1",
dataSource: "Data Source Identifier",
rootSource: "Root Source Identifier",
contentType: "text/plain",
data: "Comment data 1",
creator: "Creator Identifier",
collectionId: "Collection Identifier",
transferable: true,
tags: [
{ name: "Data-Source", value: "Data Source Identifier" },
{ name: "Root-Source", value: "Root Source Identifier" },
],
},
{
id: "CommentProcessId2",
title: "Comment Title 2",
description: "Comment Description 2",
dataSource: "Data Source Identifier",
rootSource: "Root Source Identifier",
contentType: "text/plain",
data: "Comment data 2",
creator: "Creator Identifier",
collectionId: "Collection Identifier",
transferable: true,
tags: [
{ name: "Data-Source", value: "Data Source Identifier" },
{ name: "Root-Source", value: "Root Source Identifier" },
],
},
];
Collections are structured groups of atomic assets, allowing for cohesive representation, management, and categorization of digital items. Collections extend the concept of atomic assets by introducing an organized layer to group and manage related assets. (Read the spec).
const commentId = await permaweb.createCollection({
title: "Sample collection title",
description: "Sample collection description",
creator: profileId,
thumbnail: "Thumbnail image data",
banner: "Banner image data",
});
Parameters
args
: Object containingtitle
,description
,creator
,thumbnail (optional)
, andbanner (optional)
Response
CollectionProcessId;
const commentId = await permaweb.updateCollectionAssets({
collectionId: collectionId,
assetIds: ["AssetId1", "AssetId2", "AssetId3"],
profileId: profileId,
updateType: "Add",
});
Parameters
args
: Object containingcollectionId
,assetIds
,profileId
, andupdateType ('Add' | 'Remove')
Response
CollectionProcessUpdateId;
const collection = await permaweb.getCollection(collectionId);
Parameters
collectionId
: The ID of the collection to fetch
Response
{
id: 'Id',
title: 'Title',
description: 'Description',
creator: 'Creator',
dateCreated: 'DateCreated',
thumbnail: 'ThumbnailTx',
banner: 'BannerTx',
assets: ['AssetId1', 'AssetId2', 'AssetId3']
}
const collections = await permaweb.getCollections();
Parameters
args
: Object containingcreator (optional)
Response
[
{
id: "Id",
title: "Title",
description: "Description",
creator: "Creator",
dateCreated: "DateCreated",
thumbnail: "ThumbnailTx",
banner: "BannerTx",
assets: ["AssetId1", "AssetId2", "AssetId3"],
},
{
id: "Id",
title: "Title",
description: "Description",
creator: "Creator",
dateCreated: "DateCreated",
thumbnail: "ThumbnailTx",
banner: "BannerTx",
assets: ["AssetId1", "AssetId2", "AssetId3"],
},
];
To avoid the need for creating many instances in your frontend application, this react provider can be used as a reference.
import Arweave from "arweave";
import { connect, createDataItemSigner } from "@permaweb/aoconnect";
import Permaweb from "@permaweb/libs";
const PermawebContext = React.createContext<PermawebContextState>({ libs: null });
export function usePermawebProvider(): PermawebContextState {
return React.useContext(PermawebContext);
}
export function PermawebProvider(props: { children }) {
const [libs, setLibs] = React.useState(null);
React.useEffect(() => {
let dependencies = { ao: connect(), arweave: Arweave.init() };
if (wallet) dependencies.signer = createDataItemSigner(wallet);
setLibs(Permaweb.init(deps));
}, [wallet]);
}
return (
<PermawebContext.Provider value={{ libs: libs }}>
{props.children}
</PermawebContext.Provider>
);
import { usePermawebProvider } from "providers/PermawebProvider";
export default function MyComponent() {
const permawebProvider = usePermawebProvider();
React.useEffect(() => {
(async function () {
const asset = await permawebProvider.libs.getAtomicAsset(id);
})();
}, [permawebProvider.libs]);
return <h1>Permaweb Libs Component</h1>;
}