Skip to content
LogoLogo

create

Creates a new nautilus instance.

Usage

import { ,  } from 'ethers'
import {  } from '@deltadao/nautilus'
 
const  = new ('https://rpc.dev.pontus-x.eu')
const  = new ('0x...', )
 
const  = await .(, { 
  : { : 'https://node.example.org' } 
}) 

The chain is read from the signer's provider, so there is no chain parameter. nautilus then merges ConfigHelper's defaults for that chain with whatever you pass in config. A config.chainId that differs from the provider's chain throws, because the contract addresses would then belong to another chain than the transactions.

oceanNodeUri must be https://, except on localhost, 127.0.0.0/8, ::1 and *.localhost: the plaintext DDO pointer and the signed DDO go to the node for encryption. See allowInsecureTransport.

Returns

  • Type: Promise<Nautilus>

Parameters

signer

  • Type: Signer (ethers v6)

nautilus v2 requires ethers v6. A v5 Signer is not structurally compatible.

options (optional)

  • Type: NautilusOptions

Properties

config
  • Type: Partial<Config>

Overrides merged over ConfigHelper's defaults. chainId, if you pass it, must be the chain the signer's provider is on.

config.escrow, when you pass it, is the only escrow contract paid compute funds. Leave it out to fund the chain's EnterpriseEscrow from Ocean's address data (its Escrow where the data lists no EnterpriseEscrow). The escrow ConfigHelper fills in is the plain Escrow and does not count as your choice; spreading ConfigHelper's config into config would make it one, so leave its escrow out. On Pontus-X devnet, whose address data lists no escrow, set the chain's EnterpriseEscrow contract here.

One oceanNodeUri now replaces v1's metadataCacheUri and providerUri — a single ocean-node serves metadata, provider services and the indexer. There is no subgraphUri: pricing comes from chain reads.

const  = await .(, {
  : { 
    : 'https://node.example.org', 
    : '0x...', 
    : '0x...', 
    : '0x...'
  } 
})
remoteStore
  • Type: RemoteStore

Where the encrypted DDO envelope is stored. Required to publish or edit, because nautilus writes an encrypted { remote } pointer on chain rather than the document itself.

Use IpfsRemoteStore, which posts to any IPFS upload endpoint — a Kubo node, or a pinning service such as Pinata:

const  = await .(, {
  ,
  : new ({ 
    : 'http://127.0.0.1:5001/api/v0/add', 
    : 'upload'
  }) 
})

ocean-node resolves the pointer through the same storage layer it uses for asset files, so a custom RemoteStore can also return a url, s3, arweave or ftp pointer, and nautilus ships an S3RemoteStore too. NodePersistentRemoteStore is rejected: ocean-node 4.2 cannot read a DDO from its own bucket storage. See remote stores.

ddoSigner
  • Type: DdoSigner

Signs the DDO as a verifiable credential. Defaults to Eip191VcSigner, which signs with the Ethereum key and sets the issuer to the signer's address.

Pass a WaltIdVcSigner to issue from a real DID instead — see the identity guide.

credentials
  • Type: CredentialProvider

Answers the verifiable-presentation request of a service whose SSIpolicy asks for credentials. nautilus opens the policy-server session itself, so a service gated by addresses only needs no provider. Without one, a service that asks for a presentation is refused before anything is spent. See credential-gated assets.

const  = await .(, {
  ,
  : new (.(), { 
    : 'https://wallet.example.org'
  }) 
})
sessionStore

Where this instance caches its policy-server sessions, one per (node, asset, service, consumer). Only sessions the policy server opened and, where a presentation was asked for, the verifier accepted are stored. A store of your own gets only sessions opened without a presentation; presented ones stay in memory unless persistPresentedSessions. Session ids are credentials: keep the store private.

persistPresentedSessions
  • Type: boolean
  • Default: false

Also keep presented sessions (a service whose SSIpolicy asks for credentials) in sessionStore. The id of such a session lets anyone read the presentation (vp_token) through the node until the verifier forgets it, so opt in only for a store no one else can read. nautilus warns once when it is on.

sessionTtlMs
  • Type: number
  • Default: DEFAULT_SESSION_TTL_MS (2 minutes)

How long a cached policy-server session is reused, in milliseconds from when it was opened. An older one is opened again, before anything is ordered. walt.id's verifier keeps a presentation session for 5 minutes from its creation, and the session must still be alive when the node checks it after the orders, so keep this well below that. 0 caches nothing.

allowInsecureTransport
  • Type: boolean
  • Default: false

Accept a plain http:// oceanNodeUri on a host other than localhost, 127.0.0.0/8, ::1 or *.localhost, for example on a private network. Without it, create throws for such a URI. The URI is judged as fetch parses it, so http:host counts as plain http://; see the ocean-node URI. A peer id or multiaddr is not affected. The node client applies the same setting to the service endpoints it encrypts and checks files on.

S3RemoteStore and IpfsRemoteStore have their own allowInsecureTransport option for their endpoints.

requestTimeoutMs
  • Type: number
  • Default: 120000 (120 s)

How long one encrypt call to the node may take, including the signature and one retry after a rejected nonce. Over HTTP it also bounds an initialize request, and the signing of a getComputeLogs request; the log request itself waits for the job's first output with no timeout (pass signal to stop it). Passed to the node clients create builds; see OceanNodeClient.

logger
  • Type: LoggingOptions | Logger, where LoggingOptions is { level?, format?, components?, sink? }
  • Default: the process-wide configuration

This instance's own logging, e.g. one sink per tenant in a multi-tenant server. Pass either:

  • options: the instance gets a logger of its own. Options you leave out follow configureLogging;
  • a Logger made with createLogger(options): the same rules, but several instances (e.g. one tenant's instances on several chains) can share it, and with it the memory of which once-only warnings were already printed.

The events of other instances are not affected. The instance passes its logger to its node clients, its policy-session resolver and every call it makes. An S3RemoteStore has no logger of its own: its warnings go to the process-wide configuration, so give that a sink too.

const  = await .(, {
  ,
  : { : 'info', :  } 
})
const  = ({ : 'info', :  }) 
const  = await .(, { ,  }) 
nonceManagement
  • Type: 'auto' | 'off'
  • Default: 'auto'

Who chooses transaction nonces. nautilus wraps the signer in a nonce guard (getSigner returns it). With 'auto' and a signer that signs locally (an ethers Wallet), it sends one transaction at a time per chain and address, with the nonce max(its counter, the pending count), and recovers from a nonce refusal: a transaction the chain already has is waited for, never sent again; one it does not have is sent again with a fresh nonce, at most three attempts in all (an "already known" refusal is never sent again); an order, purchase, approval or escrow payment only with proof from two RPCs (needs verificationProvider) that the first can never be mined, otherwise it stops with a NonceGuardError ("may have been sent"). Wallet-managed signers (JsonRpcSigner, browser wallets) keep choosing their own nonces. 'off': nautilus never sets a nonce and never resends. Either way a refused transaction the chain already has is returned, and the cause of a failed send is named. In-process only: use one key per process. See Concurrency and nonces. Given another instance's getSigner, the new instance applies its own nonceManagement and verificationProvider to the signer underneath, and shares the per-address order and nonce counter with the first.

verificationProvider
  • Type: Provider (ethers)
  • Default: none (the signer's provider, read twice)

A second, independent RPC provider for the same chain (not the signer's own provider, nor one with the same URL: create refuses both), read in every proof that a transaction was never sent: before an order, purchase, approval or escrow payment is sent again after a nonce refusal, and before an envelope is removed after a metadata transaction refused for its nonce. Without it, a transaction that moves value is never sent again: it stops with "may have been sent". Recommended for paid flows, where a single load-balanced RPC whose transaction index lags could make a mined order look unsent.

maxProviderFee
  • Type: TokenAmount | TokenAmount[], where TokenAmount is { token: string; amount: bigint | string }

The default ceiling on the provider fees of every access and compute call, per token, in the token's smallest unit.

The four options are defaults in two pairs: maxProviderFee with confirmProviderFees, and maxEscrowPayment with confirmEscrowPayment. A call that sets either option of a pair, even to undefined, uses its own pair and neither default of it. So a call with a tighter maxProviderFee does not inherit a permissive confirmProviderFees from here, and a call can clear a default by passing the option as undefined.

confirmProviderFees
  • Type: (fees: ProviderFeeQuote[]) => boolean | Promise<boolean>

The default confirmation for provider fees maxProviderFee does not cover, for example to ask a user. A call that sets maxProviderFee or confirmProviderFees does not use it. See access.

maxEscrowPayment
  • Type: TokenAmount | TokenAmount[]

The default ceiling on what one compute job may lock in escrow, per payment token, in the token's smallest unit. A call that sets maxEscrowPayment or confirmEscrowPayment does not use it.

nautilus funds exactly one escrow contract, whatever contract the node names:

  1. config.escrow, when you set it: that contract, and no other;
  2. otherwise the chain's EnterpriseEscrow in Ocean's address data (ocean.js's bundled addresses, or the file ADDRESS_FILE names), the contract ocean-node 4.2.0 uses where the address data has one (OP Sepolia among them);
  3. otherwise the chain's Escrow.

On a chain with neither (Pontus-X devnet among them), set the chain's EnterpriseEscrow contract as config.escrow, or paid compute is refused. See Escrow contract.

confirmEscrowPayment
  • Type: (payment: EscrowPaymentQuote) => boolean | Promise<boolean>

The default confirmation for an escrow payment maxEscrowPayment does not cover. A call that sets maxEscrowPayment or confirmEscrowPayment does not use it. See compute.

Paid compute jobs of one instance that share a chain, payer, payment token and environment account fund escrow and start one at a time, so concurrent jobs do not overwrite each other's escrow authorisation. Jobs from another instance or process are not covered; see Concurrent jobs.

Throws

  • When config.chainId differs from the chain of the signer's provider, or the signer has no provider.
  • When oceanNodeUri is missing, or is plain http:// on a non-loopback host without allowInsecureTransport.
  • When nftFactoryAddress, fixedRateExchangeAddress or dispenserAddress is missing or not an address, or escrow is set but is not an address.
  • When nonceManagement is neither 'auto' nor 'off', or verificationProvider is on another chain than the signer, or is the signer's own provider (the same object or URL).
  • When maxProviderFee or maxEscrowPayment has an entry whose token is not an address, whose amount is not a non-negative integer, or whose token is listed twice, or when confirmProviderFees or confirmEscrowPayment is not a function.