AssetBuilder
Builds the metadata for an asset you want to publish or edit, with a typesafe fluent API.
Instantiating
Two modes, chosen by whether you pass an existing asset.
import { } from '@deltadao/nautilus'
const = new ()
an empty asset, to be filled inimport { , } from '@deltadao/nautilus'
import { } from 'ethers'
const = await .(new ('0x1234'))
const = await .(
'did:ope:2a6ebce0af9361e2c7d1e1e7909ecac3e4cabb4f089f7edd51865e0b77a5c216'
)
const = new () In edit mode the builder seeds itself from the published document, including its owner and lifecycle state, and immediately strips the indexer-derived fields so they can never be signed back in. Setting one field leaves everything else intact: the merge is structural, not top-level, so you never have to resupply metadata you are not changing.
reset() returns to whichever state the constructor produced. In edit mode that means the
loaded asset — v1 emptied the builder, which made reset() unusable while editing.
A minimal new asset
const = new ()
.('dataset') // required
.('Hourly Weather Observations') // required
.('deltaDAO AG') // required by DDO v5
.() // at least one
.()build() rejects a new asset missing name, type or providedBy, and one with no
services. An algorithm also needs container metadata. Everything else is checked by
publish, which validates the whole DDO locally against the
DDO v5 schema before spending gas.
DDO v5 changes worth knowing
Three setters take the same arguments as in v1 but produce a different shape, because DDO v5 changed the fields. The builder absorbs that, so you keep passing plain strings.
// Stored as { '@value', '@language', '@direction' } — v4 used a plain string.
.('One row per hour, comma separated')
// Stored as { name } — v4 used a plain string. Pass the object form for ODRL terms.
.('https://market.oceanprotocol.com/terms')
// Stored as a { label: url } map — v4 used an array. An array still works, keyed by index.
.(['https://docs.example'])
.({ : 'https://docs.example' })setContentLanguage was repurposed. In v4 it wrote a contentLanguage metadata field;
v5 moved the language onto each value, so it now sets the tag applied to every
language-tagged field the builder emits:
.('de', 'ltr')
.('Stündliche Wetterbeobachtungen')
description: { '@value': '...', '@language': 'de', '@direction': 'ltr' }It defaults to en / ltr.
Gating access
Address lists work as they did in v1. Verifiable-credential gating is new in DDO v5.
// Only these addresses may access it.
.(., ['0x0DB823218e337a...'])
// And: a credential of this type, from an issuer you trust.
.(., [
{
: 'VerifiableId',
: 'jwt_vc_json',
: [{ : 'allowed-issuer', : ['did:web:issuer.example'] }]
}
])
.(., ['signature', 'not-before'])
// And: a presentation signed by the DID it names, holding at least one credential.
.(., [
{ : 'signature' },
{ : 'minimum-credentials', : '1' }
]) On a node with a policy server the address allow list is required, and it is the check that
holds. Until the policy server enforces the requested credential type, the credential check
stops only consumers who use a normal wallet: anyone who builds their own presentation passes
it with a self-issued credential of another type. An allow list containing '*' therefore
leaves no gate at all, so list the allowed addresses explicitly.
See the known limitation.
See Credential-gated assets for the whole picture, including the consumer side.
Method reference
Metadata
setType ·
setName ·
setDescription ·
setDisplayTitle ·
setAuthor ·
setProvidedBy ·
setCopyrightHolder ·
setLicense ·
setAlgorithm ·
setContentLanguage ·
addTags ·
addCategories ·
addLinks ·
addAttachments ·
addAdditionalInformation
Services
NFT
setNftData ·
setNftTokenName ·
setNftTokenSymbol ·
setNftTokenUri ·
setNftTokenTransferable ·
setNftTokenTemplate
Identity and gating
setIssuer ·
addCredentialAddresses ·
removeCredentialAddresses ·
addCredentialAccessList ·
addRequestCredentials ·
setVcPolicies ·
setVpPolicies ·
setCredentialMatchRules