NFT Processing Unit
Nurond is a low level engine that lets you create and manage NFTs from HTTP requests. It is made up of:
- Programmable Wallet: automatically sign messages by POSTing messages to sign over HTTP
- NFT File System: store and manage IPFS files both locally and publish when ready
- NFT Database: store signed tokens locally and publish when ready
If you're looking for a way to download nurond, check out the Tutorial here: https://tutorial.cell.computer/#/?id=_2-download-nuron
Once installed, you can interact with your Nurond using HTTP requests:
- Use the HTTP API directly: You can use whatever programming language you want (python, javascript, ruby, etc.)
- Use a JavaScript library: nuron.js is just a wrapper library that makes it easy to interact with a Nurond using simple JavaScript code.
You don't have to use nuron.js. You can build your own Nuron client, or just directly program networking code to interact with Nurond, using any programming language. It's simple because Nurond is just a local HTTP server.
Check out the API reference section below for all available endpoints. For example, for GET /wallet/accounts
, you can do this:
let accounts = await fetch("http://localhost:42000/wallet/accounts").then((res) => {
return res.json()
})
Get all local account names (The names you save seed phrases under:)
GET /wallets/accounts
returns:
{
"response": [
<account name>,
<account name>,
...
]
}
GET /wallet/session?path=<bip44 derivation path>
returns the corresponding account for the bip44 derivation path:
{
"response": {
"username": <account name>,
"address": <address>
}
}
- if logged in
- if the
bip44 derivation path
was passed, returns both theusername
and theaddress
of the wallet address at the derivation path. - if the
bip44 derivation path
was not passed, only returns theusername
of the current session.
- if the
- if not logged in, returns the response with a
username
ofnull
Get first 100 addresses derived from the currently logged-in wallet for the specified chainId
GET /wallet/chains/:chainId
returns
{
"response": {
"name": <logged in account name>,
"chain": <the blockchain symbol>,
"chainId": <the requested blockchain chainId>,
"accounts": [{
"address": <address 0>,
"path": <bip44 derivation path 0>,
}, {
"address": <address 1>,
"path": <bip44 derivation path 1>,
}, {
...
}, {
"address": <address 99>,
"path:" <bip44 derivation path 99>,
}]
}
}
POST /wallet/connect
{
"username": <username>,
"password": <key encryption password>
}
returns:
{
"success": true
}
or if there's an error:
{
"error": <error message>
}
Sign out of the current session
POST /wallet/disconnect
returns:
{
"success": true
}
or if there's an error:
{
"error": <error message>
}
delete the wallet for the current session. Will only delete successfully if the encryption password is correct
POST /wallet/delete
{
"password": <key encryption password>
}
returns:
{
"success": true
}
or if there's an error:
{
"error": <error message>
}
Export a wallet
POST /wallet/export
{
"key": <bip44 derivation path>,
"password": <key encryption password>
}
returns:
{
"response": <exported value (seed phrase or private key)>
}
- if the
key
attribute is included in the payload- the private key (hex format) at the bip44 derivation path will be exported
- if the
key
attribute is NOT included in the payload- the seed phrase is exported
Import a seed
phrase, encrypt it with password
, and store it under username
account on Nurond.
POST /wallet/import
{
"response": {
"seed": <seed phrase>,
"username": <username to assign to the new wallet>,
"password": <key encryption password>
}
}
returns:
{
"response": {
"username": <the username for the imported wallet>,
"seed": <the imported seed phrase>,
"encrypted": <the encrypted seed phrase>
}
}
or if there's an error:
{
"error": <error message>
}
generate a random seed phrase, encrypt it with the password
and store it under the username
account on Nurond.
POST /wallet/generate
{
"username": <username>,
"password": <key encryption password>
}
returns:
{
"response": {
"username": <the username for the generated wallet>,
"seed": <the generated seed phrase>,
"encrypted": <the encrypted seed phrase>
}
}
or if there's an error:
{
"error": <error message>
}
Get the files at :path
within the Nurond file system.
For example,
GET /raw/cube/web/index.html
returns the index.html
file under the cube
workspace folder
Get the current file system configuration
GET /fs/config
returns
{
"ipfs": {
"key": <nft.storage APK key>
},
"workspace": {
"home": <the folder path where the nurond stores everything>
}
}
POST /fs/configure
{
"ipfs": {
"key": <nft.storage API key>
}
}
if successful, returns:
{
"success": true
}
if failed, returns the error message:
{
"error": <error message>
}
Ask Nurond to save a Buffer object to the file system. Here's an example JavaScript code to make the POST request:
let save = (data) => {
let type = data.constructor.name;
let blob;
if (type === 'ArrayBuffer') {
// If ArrayBuffer, transform into Blob
blob = new Blob([data])
} else if (type === "File" || type === "Blob" || type === "Buffer") {
// Otherwise if they're File, Blob, or Buffer, use the data as is
blob = data
}
// Create a formdata object
let fd = new FormData()
// Attach the blob under the "file" field
fd.append('file', blob, { filename: "filename" })
// Attach the workspace folder path to store the file under
fd.append('workspace', workspace_folder_path)
// Make the POST request
let r = await fetch("/fs/binary", {
method: "POST",
body: fd
}).then((res) => {
return res.json()
})
}
save a JSON to the file system. Here's an example JavaScript code for posting to the /fs/object
endpoint:
let save = (json) => {
let r = await fetch("/fs/json", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(json)
}).then((res) => {
return res.json()
})
}
remove cids from the fs
folder
POST /fs/rm
{
"workspace": <the nurond workspace path>,
"cids": <an array of IPFS cids to remove from the fs folder>
}
The cids
can be:
- an array of IPFS CIDs: remove all files with the CIDs
- a single IPFS CID: remove a single file
*
: remove all files under thefs
folder in the specified workspace
if successful, returns
{
"success": true
}
if failed, returns:
{
"error": <error message>
}
POST /fs/pin
{
"workspace": <nurond workspace folder path>,
"cid": <The IPFS cid of the file to pin>
}
where:
cid
can be one of the following:- : The IPFS CID of the file to pin
- **"*": ** Pin the entire
fs
folder
returns
{
"response": <pinned cid>
}
Lf you want to pin the entire fs
folder within the Nurond project folder canvas
, you can make a POST request without the cid
attribute:
POST /fs/pin
{
"workspace": "canvas",
}
If you want to pin a specific file inside the fs
folder, you can do:
POST /fs/pin
{
"workspace": "canvas",
"cid": "bafkreihly2rt63htnzhxqjgixknywcty53zhcxmyskj3l2gzwdchr6adle""
}
builds an unsigned token according to the payload description:
POST /token/build
{
"payload": {
"body": <token body description>,
"domain": <token domain description>
}
}
returns the generated unsigned token:
{
"body": <generated token body (NO signature)>,
"domain": <generated token domain>
}
signs an unsigned token to create a signed token:
POST /token/sign
{
"key": <bip44 derivation path>,
"payload": <unsigned token (constructed with build)>
}
signs the unsigned token and attaches the signature and returns a signed token, which has the exact same schema as an unsigned token, except that the signature is attached at body.signature
path of the JSON:
{
"body": <token body with "signature" attached>,
"domain": <generated token domain>
}
POST /token/create
{
"key": <bip44 derivation path>,
"payload": {
"body": <token body description>,
"domain": <token domain description>
}
}
returns the generated token:
{
"body": <generated token body, with signature>,
"domain": <token domain>
}
The Nurond DB is powered by Mixtape.
save objects to the database at mixtape.db
.
POST /db/write
{
"workspace": <nurond workspace folder path>,
"table": <table name>,
"payload": <signed or unsigned token, or a metadata object>
}
the table
attribute can be one of the following:
token
: A table that can be used to store all the signned and unsigned tokensmetadata
: A table that can be used to store all the NFT metadata
returns the generated IPFS CID for the token:
if successful, returns:
{
"success": true
}
or if there's an error:
{
"error": <error message>
}
read the sqlite database stored inside the file mixtape.db
at a specified path:
POST /db/read
{
"workspace": <nurond workspace folder path>,
"table": <table name>,
"payload": <query language>
}
the table
attribute can be one of the following:
token
: A table that can be used to store all the signned and unsigned tokensmetadata
: A table that can be used to store all the NFT metadata
If successful, returns:
{
"response": <the result array of the Mixtape read() method>
}
If failed, returns:
{
"error": <error message>
}
read the sqlite database stored inside the file mixtape.db
at a specified path:
POST /db/readOne
{
"workspace": <nurond workspace folder path>,
"table": <table name>,
"payload": <query language>
}
the table
attribute can be one of the following:
token
: A table that can be used to store all the signned and unsigned tokensmetadata
: A table that can be used to store all the NFT metadata
If successful, returns:
{
"response": <the result object of the Mixtape readOne() method>
}
If failed, returns:
{
"error": <error message>
}
Deletes the rows that match the query
POST /db/rm
{
"workspace": <nurond workspace folder path>,
"table": <table name>,
"payload": <query language>
}
the table
attribute can be one of the following:
token
: A table that can be used to store all the signned and unsigned tokensmetadata
: A table that can be used to store all the NFT metadata
If successful, returns:
{
"success": true
}
If failed, returns:
{
"error": <error message>
}
Build a static site for the workspace at path workspace
for the tokens of domain
. Builds the following web pages, which you can publish immediately to the web and let people mint:
index.html
: the home page that dieplays all tokenstoken.html
: individual token minting page
POST /web/build
{
"workspace": <nurond workspace folder path>,
"domain": <token domain>,
"templates": <templates array (optional)>
}
Where <templates array>
is an array of template mapping objects, each of which has the following attributes:
src
: the ejs template location (HTTP URL or file path)dest
: the file names to create render from thesrc
template files.
Here's an example:
{
"workspace": <nurond workspace folder path>,
"domain": <token domain>,
"templates": [{
"src": "https://myserver.com/index.ejs",
"dest": "index.html"
}, {
"src": "https://myserver.com/token.ejs",
"dest": "token.html"
}]
}
if successful, returns:
{
"success": true
}
or if there's an error:
{
"error": <error message>
}
Copy everything in the workspace into the published
subfolder in the workspace, which will be available publicly.
This is not very useful when using nurond directly, but when you use high level systems like Nuron, which adds an authentication layer.
With Nuron, only the administrator can access the admin dashboard and access the files.
But the "published" folder is an exception. Once you put files into the published folder, they will be available publicly.
POST /web/publish
{
"workspace": <nurond workspace folder path>
}