Remote stores
Where the signed DDO actually lives
In v1 the DDO went on chain. In v2 it does not: nautilus signs the document as a verifiable
credential, stores it somewhere off chain, and writes only a pointer —
{ remote: <StorageObject> } — into the NFT's metadata.
That is why publishing needs a remote store, and why
publish throws without one.
The publish path: the document is signed and stored off chain, and only its pointer is written on chain, where ocean-node dereferences it to index the asset.
The default: the node's own storage
NodePersistentRemoteStore writes to ocean-node's persistent storage, so you need no
external infrastructure at all. It takes a node client, which is why the instance is built in
two steps.
const = await .(, { })
const = await .(, {
,
: new (.())
})It creates a bucket on demand. Pass bucketId to reuse one, accessLists to restrict who
can read it, or label to name it.
IPFS
const = new ({
: 'http://127.0.0.1:5001/api/v0/add'
}) uploadUrl is the Kubo RPC add endpoint. Add headers for an authenticated gateway, and
extractCid if your gateway returns the CID under a key other than the usual
Hash/cid/IpfsHash.
What ocean-node accepts
The node's isRemoteDDO accepts an object with exactly one key, remote, and hands it to
the same storage resolver it uses for asset files. So any storage type it supports for files
works for the DDO too:
type | pointer shape |
|---|---|
ipfs | { type, hash } |
url | { type, url, method } |
arweave | { type, transactionId } |
s3 | { type, s3Access } |
ftp | { type, url } |
nodePersistentStorage | { type, bucketId, fileName } |
Writing your own
The interface is one method.
class implements RemoteStore {
async (: string, : { : string }): <> {
const = await (, `${.}.json`)
return { : 'url', , : 'GET' } as
}
}
declare function (: string, : string): <string>payload is the signed DDO. hint.did is a stable name, for stores that need a key. Return
any pointer shape from the table above — nautilus wraps it with toRemotePointer before it
goes on chain.
Overriding per call
The instance's store is the default; a single publish can use a different one.
await .(, {
: new ({ : 'http://127.0.0.1:5001/api/v0/add' })
})