Get started
Glacier SDK supports Node.js and Browser simultaneously, which means that developers can not only create Dataset and Collection on the server side through the private key controlled by themselves but also support users to control all their data through the Ethereum wallet in the browser. This chapter will introduce how to get started with the Glacier SDK quickly
Use in Node.js
Using Glacier SDK in Node.js is very easy and only requires a few steps:
Install the SDK
Execute commands in your Node.js project
pnpm add @glacier-network/client
Import SDK
To use SDK, you only need to import the GlacierClient class in @glacier-network/client and then create an instance, for example:
import { GlacierClient } from '@glacier-network/client';
const arweaveEndpoint = 'https://p0.onebitdev.com/glacier-gateway';
// const filEndpoint = ''https://web3storage.onebitdev.com/glacier-gateway';
// const greenFieldEndpoint = 'https://greenfield.onebitdev.com/glacier-gateway';
const client = new GlacierClient(arweaveEndpoint);
The first parameter of the instantiation is the address of the Glacier node to be connected.
After the instantiation is completed, the read-only query of the Glacier data can be executed through the client. If you want to write or modify the data, you need to specify your own Ethereum wallet private key when creating the instance:
import { GlacierClient } from '@glacier-network/client';
const privateKey = `0xf7311f908890f7aeaf46d0185cf4234ae926cf896b2c50590d6735a37c827045`;
const client = new GlacierClient('https://p0.onebitdev.com/glacier-gateway', {
privateKey,
});
Now you can read and write data, a complete sample project as below:
https://github.com/Glacier-Labs/js-glacier/tree/main/apps/sdk-example
Supported Endpoint
| DA Chain | Endpoint | Status |
|---|---|---|
| Arweare | https://p0.onebitdev.com/glacier-gateway | Mainnet |
| Filecoin | https://web3storage.onebitdev.com/glacier-gateway | Testnet |
| BNB Greenfield | https://greenfield.onebitdev.com/glacier-gateway | Testnet |
Now We supported Arweave/Filecoin/BNB Greenfield As Glacier DA Layer. Current Version these DA Layers are isolated, we will make them configurable and dynamic in the future.
Use in browser
For Web3 applications, users usually operate their data through the Ethereum wallet in the browser. However, unlike Node.js, the browser cannot access the user's private key, so signature authorization can only be performed through the Ethereum wallet, such as MetaMask, WalletConnect. After completing this step, the subsequent usage is consistent with Node.js.
Create project
We can create a react-ts template project based on Vite. If it is integrated with an existing project, you can skip this step
pnpm create vite glacier-quickstart --template react-ts
The complete sample https://github.com/Glacier-Labs/glacier-quickstart
More complex project can refer to https://github.com/Glacier-Labs/js-glacier/tree/main/apps/playground
Install SDK
Enter glacier-quickstart directory and execute the command
pnpm add @glacier-network/client
Connect wallet
Next, we create a React Hook to connect to the browser wallet MetaMask. The code is as follows:
import { useState, useEffect, useCallback } from 'react';
import { MetaMaskInpageProvider } from '@metamask/providers';
export default function useMetaMask() {
const [account, setAccount] = useState<string>();
const [provider, setProvider] = useState<MetaMaskInpageProvider>();
const connect = useCallback(async () => {
const accounts = await window.ethereum.request<string[]>({
method: 'eth_requestAccounts',
params: [],
});
if (accounts) setAccount(accounts[0]);
}, []);
const eagerConnect = useCallback(async () => {
if (!window.ethereum) return;
const accounts = await window.ethereum?.request<string[]>({
method: 'eth_accounts',
params: [],
});
if (accounts) setAccount(accounts[0]);
setProvider(window.ethereum);
}, []);
useEffect(() => {
window.ethereum?.on('accountsChanged', (args) => {
const accounts = args as string[];
if (accounts) setAccount(accounts[0]);
setProvider(window.ethereum);
});
}, []);
return {
account,
provider,
connect,
eagerConnect,
};
}
Connect Glacier
To operate the data of Glacier, you need to sign in through the Ethereum wallet. So now we create another Hook to encapsulate the relevant operations, which includs:
- Instantiate
GlacierClient - Create
Namespace - Enum
Namespace
The creation of Namespace will call the wallet for signature confirmation.
import { useState, useCallback, useMemo, useEffect } from 'react';
import { GlacierClient, NamespaceRecord } from '@glacier-network/client';
import useMetaMask from './useMetaMask';
export default function useGlacier() {
const [spaces, setSpaces] = useState<NamespaceRecord[]>([]);
const { provider, account, connect, eagerConnect } = useMetaMask();
const client = useMemo(() => {
return new GlacierClient('https://p0.onebitdev.com/glacier-gateway', {
provider,
});
}, [provider]);
const listNamespace = useCallback(async () => {
if (!account) return setSpaces([]);
const result = await client.namespaces(account);
setSpaces(result);
}, [client, account]);
const createNamespace = useCallback(
async (name: string) => {
const result = await client.createNamespace(name);
return result;
},
[client]
);
useEffect(() => {
listNamespace();
}, [listNamespace]);
return {
client,
spaces,
account,
connect,
eagerConnect,
listNamespace,
createNamespace,
};
}
Pay attention to this part from the above codes:
const client = useMemo(() => {
return new GlacierClient('https://p0.onebitdev.com/glacier-gateway', {
provider,
});
}, [provider]);
When instantiating GlacierClient, provider, that is, window.ethereum is passed in instead of privateKey, which is also the main difference between Browser and Node.js. If you use other popular wallet connection libraries in your project, such as web3-react, you can refer to the following usage:
import { useWeb3React } from '@web3-react/core';
import { Web3Provider } from '@ethersproject/providers';
export default function App() {
const { account, library } = useWeb3React<Web3Provider>();
const client = new GlacierClient('https://p0.onebitdev.com/glacier-gateway', {
provider: library?.provider,
});
}
Write component
Finally, let's write a React component to connect the previous Hook. The code is as follows:
import { useEffect, useState } from 'react';
import { Button, Form, ListGroup } from 'react-bootstrap';
import useGlacier from './useGlacier';
export default function App() {
const [name, setName] = useState('');
const [loading, setLoading] = useState(false);
const {
account,
spaces,
connect,
eagerConnect,
createNamespace,
listNamespace,
} = useGlacier();
useEffect(() => {
eagerConnect();
}, [eagerConnect]);
const onCreate = async () => {
try {
setLoading(true);
const result = await createNamespace(name);
await listNamespace();
alert(result.insertedId);
} catch (error) {
console.trace(error);
} finally {
setLoading(false);
}
};
if (!window.ethereum) {
return (
<div className="container my-3">
<a href="https://metamask.io/" target="_blank" rel="noreferrer">
<Button>Install MetaMask</Button>
</a>
</div>
);
}
if (!account) {
return (
<div className="container my-3">
<Button variant="success" onClick={connect}>
Connect Wallet
</Button>
</div>
);
}
return (
<div className="container">
<div className="my-3">Connected: {account}</div>
<Form>
<Form.Group className="mb-3">
<Form.Control
type="text"
placeholder="Namespace"
value={name}
onChange={(e) => {
setName(e.target.value.trim());
}}
/>
</Form.Group>
<Button
variant="primary"
disabled={loading || !name}
onClick={onCreate}
>
Create Namespace
</Button>
</Form>
<div className="my-3">My Namespaces:</div>
<ListGroup>
{spaces.map((item) => (
<ListGroup.Item key={item.namespace}>{item.namespace}</ListGroup.Item>
))}
</ListGroup>
</div>
);
}
Well done! Check the following result: