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
- Type:
SessionStore - Default: a
MemorySessionStore
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, whereLoggingOptionsis{ 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
Loggermade withcreateLogger(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[], whereTokenAmountis{ 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:
config.escrow, when you set it: that contract, and no other;- otherwise the chain's
EnterpriseEscrowin Ocean's address data (ocean.js's bundled addresses, or the fileADDRESS_FILEnames), the contract ocean-node 4.2.0 uses where the address data has one (OP Sepolia among them); - 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.chainIddiffers from the chain of the signer's provider, or the signer has no provider. - When
oceanNodeUriis missing, or is plainhttp://on a non-loopback host withoutallowInsecureTransport. - When
nftFactoryAddress,fixedRateExchangeAddressordispenserAddressis missing or not an address, orescrowis set but is not an address. - When
nonceManagementis neither'auto'nor'off', orverificationProvideris on another chain than the signer, or is the signer's own provider (the same object or URL). - When
maxProviderFeeormaxEscrowPaymenthas an entry whosetokenis not an address, whoseamountis not a non-negative integer, or whose token is listed twice, or whenconfirmProviderFeesorconfirmEscrowPaymentis not a function.