On this page
Limits and costs
Every cap, format, deposit and gas figure the vault, the factory, the console and the SDK use, read from the code. It also shows who pays each cost and what a vault spends from its own NEAR.
Probarion's limits live in its code: the caps and formats the vault and the factory enforce, the deposit and gas of each call, what a vault spends from its own NEAR, and the hosted app's upload and rate limits. A test reads contracts/vault/src, contracts/factory/src/lib.rs and the TypeScript modules that define these values, and fails when a row on this page no longer matches them.
How to read the tables#
- Constant is the name in the source, such as
MAX_AGENTSincontracts/vault/src/lib.rs. A Rust value is shown as the source computes it, and a TypeScript value comes from the module that exports it. - Units. 1 NEAR is 10^24 yoctoNEAR, and 1 Tgas is 10^12 gas. Times on chain are in nanoseconds, as
block_timestampcounts them, and times in TypeScript are in milliseconds. USDC amounts travel in base units, with 6 decimals. - Past the limit and Refused with name the
PROBARION:<Code>panic a call fails with, such asInvalidInput. A panic reverts every change the call made, and Errors explains each code. - Anchors. Each row has its own anchor, such as
limits-vault-max_agentsorlimits-deposit-create_mandate.
Vault limits#
Every vault that runs the code in contracts/vault/src has these limits. No method changes the approvers, the allowed assets, the daily backstop or the hold time that new set, so a vault keeps them for life.
| Constant | Value | What it limits | Past the limit |
|---|---|---|---|
DAY_NS | 86,400,000,000,000 ns (one day) | The day of the daily backstop: a spend counts in UTC day block_timestamp / DAY_NS, and the vault's daily_backstop caps each day's total | OverDailyBackstop |
MAX_HELD_TTL_NS | 2,592,000,000,000,000 ns (30 days) | The held_ttl_ns of new: how long a held spend waits for an approver. It must also be above 0 | InvalidInput, and the vault is not created |
MAX_APPROVERS | 10 | Approvers named in new, at least 1. No method changes them after the vault is created | InvalidInput, and the vault is not created |
MAX_ASSETS | 10 | The allowed_assets of new: the Intents assets a mandate may pay out in | InvalidInput, and the vault is not created |
MAX_AGENTS | 16 | Agent keys on the vault at one time, added with add_agent | InvalidInput. Remove a key with remove_agent first |
MAX_PAGE | 100 | Items one call of list_mandates, list_spends or list_anchors returns. from_index is a position counted from 0 | None: a larger limit returns 100 items |
ONE_YOCTO | 1 yoctoNEAR | The deposit the vault attaches to its own ft_transfer and ft_withdraw calls: in each payout, in withdraw and in withdraw_intents | None: the vault sets it |
USDC_STORAGE_DEPOSIT | 1,250,000,000,000,000,000,000 yoctoNEAR (0.00125 NEAR) | What create_mandate passes to the USDC token's storage_deposit for a NEAR payee, out of the owner's deposit: the storage_balance_bounds().min of mainnet's USDC | InsufficientDeposit when the owner's deposit does not cover it and the mandate's storage |
The limits of each payment are the owner's to choose when they create a mandate. Mandates lists every field, and How a payment is checked shows the order the vault checks them in, the daily backstop included.
String and hash formats#
The vault and the factory check these shapes before they store a mandate or an agent key, take a spend, record an anchor, create a vault or add a version. A malformed value fails the call. The policy engine in @probarion/core checks a spend's invoice_hash and ref before the SDK sends it, and the console and the CLI check both labels before they build the call.
| Input | Format | Checked by | Refused with |
|---|---|---|---|
A mandate's purpose_hash, a spend's invoice_hash and decision_hash, and an anchor's root | 64 lowercase hex characters: a sha256 digest | is_hex64 | InvalidInput |
The address of a Base payee | 0x and 40 hex digits in any case, 42 characters in all. 0X is refused | is_evm_address | InvalidInput |
The address of a Solana payee | Base58 in the Bitcoin alphabet, with no 0, O, I or l, 32 to 44 characters | is_solana_address | InvalidInput |
The asset of an Intents payee | Starts with base- for a Base payee or sol- for a Solana payee, and is one of the vault's allowed_assets | asset_matches_chain | AssetNotAllowed |
A spend's ref, its idempotency key | 1 to 64 bytes. Once the vault accepts a spend, its ref stays used | is_ref | InvalidInput, or DuplicateRef for a used one |
A mandate's label | At most 64 bytes | validate_mandate | InvalidInput |
An agent key's label | At most 64 bytes | add_agent | InvalidInput |
| The memo of a payout to a Base or Solana payee | WITHDRAW_TO: and the payee's address, byte for byte. @probarion/core exports the same WITHDRAW_MEMO_PREFIX | WITHDRAW_MEMO_PREFIX | None: the vault writes it from the mandate |
| The memo of a payout to a NEAR payee | probarion: and the spend id | NEAR_MEMO_PREFIX | None: the vault writes it |
The name of create_vault | 2 to 31 characters, ^[a-z0-9][a-z0-9_-]{1,30}$. <name>.<factory> must also be a valid NEAR account id: no - or _ at the end, never two of them in a row, and at most 64 characters in all | valid_name | InvalidInput |
The code_hash of add_version | Base58 of 32 bytes. An embedded version also needs that code stored by store_code | add_version | InvalidInput |
The mode of add_version | global or embedded | add_version | InvalidInput |
The input of store_code: the raw vault wasm, sent with file-args | Not empty. The factory stores it under its sha256, which store_code returns | store_code | InvalidInput |
Factory limits#
The factory checks the new vault's limits before it creates anything, so a create_vault the vault would refuse fails in the factory and no account is made. A taken name is the one failure the factory cannot see in advance: the new account fails, and on_vault_created refunds the deposit from the factory's own balance.
| Constant | Value | What it limits | Past the limit |
|---|---|---|---|
MAX_NOTES | 256 | Bytes of notes in add_version | InvalidInput |
MAX_PAGE | 100 | Vaults one call of list_vaults returns | None: a larger limit returns 100 items |
MAX_ASSETS | 10 | The allowed_assets of the factory's new, which every vault it creates receives | InvalidInput |
MAX_APPROVERS | 10 | Approvers in create_vault, at least 1: the vault's own limit, checked before anything is created | InvalidInput, and nothing is created |
MAX_HELD_TTL_NS | 2,592,000,000,000,000 ns (30 days) | The held_ttl_ns of create_vault, above 0: the vault's own limit, checked before anything is created | InvalidInput, and nothing is created |
min_deposit, set in the factory's new | 500,000,000,000,000,000,000,000 yoctoNEAR (0.5 NEAR) on Testnet | The least create_vault accepts for a global version. An embedded version also charges the byte cost of the vault's copy of the code. get_config returns it. The Testnet factory's current version is embedded, so a Testnet vault needs min_deposit plus the code's byte cost, about 2.98501 NEAR for the 248,501-byte vault wasm, and the CLI requires --deposit for it | InsufficientDeposit, and nothing is created |
Read the factory's min_deposit and current version on testnet, with no key:
near contract call-function as-read-only vaults.probarion.testnet get_config json-args '{}' network-config testnet now
near contract call-function as-read-only vaults.probarion.testnet versions json-args '{}' network-config testnet nowDeposits and gas per call#
- Deposit the contract asks is what the method checks. "Exactly 1 yoctoNEAR" means any other amount, none included, fails with
RequiresOneYocto. Only a full-access key can attach a deposit, which is why most owner calls need one. A method whose deposit reads None is not#[payable], and near-sdk refuses a deposit sent to it. - Deposit the console and the CLI attach is what the two tools put in the transaction they prepare. Their mandate deposit has a wide margin, and the vault refunds the rest.
- Prepaid gas is the gas the console and the CLI attach, and for
spendandanchorthe gas the SDK attaches. The console and the CLI agree on every call they both build. A call signed by hand sets its own.
| Call | Signed by | Deposit the contract asks | Deposit the console and the CLI attach | Prepaid gas |
|---|---|---|---|---|
freeze on the vault | The owner, from a full-access key or a function-call key that may call the vault | None | None | 30 Tgas |
unfreeze on the vault | The owner, from a full-access key | Exactly 1 yoctoNEAR | 1 yoctoNEAR | 30 Tgas |
withdraw on the vault | The owner, from a full-access key | Exactly 1 yoctoNEAR | 1 yoctoNEAR | 100 Tgas |
withdraw_intents on the vault | The owner, from a full-access key | Exactly 1 yoctoNEAR | 1 yoctoNEAR | 150 Tgas |
create_mandate on the vault | The owner, from a full-access key | The storage the new mandate takes at the byte cost, plus USDC_STORAGE_DEPOSIT for a NEAR payee. Less is InsufficientDeposit, and the excess is refunded to the owner | 0.05 NEAR: the console's MANDATE_STORAGE_DEPOSIT and the CLI's --deposit default | 100 Tgas |
revoke_mandate on the vault | The owner, from a full-access key | Exactly 1 yoctoNEAR | 1 yoctoNEAR | 30 Tgas |
add_agent on the vault | The owner, from a full-access key | Exactly 1 yoctoNEAR | 1 yoctoNEAR | 30 Tgas |
remove_agent on the vault | The owner, from a full-access key | Exactly 1 yoctoNEAR | 1 yoctoNEAR | 30 Tgas |
set_ledger_key on the vault | The owner, from a full-access key | Exactly 1 yoctoNEAR | 1 yoctoNEAR | 30 Tgas |
approve on the vault | An approver, from a full-access key | Exactly 1 yoctoNEAR | 1 yoctoNEAR | 150 Tgas |
reject on the vault | An approver, from a full-access key | Exactly 1 yoctoNEAR | 1 yoctoNEAR | 30 Tgas |
spend on the vault | An agent key on the vault account. The vault's own NEAR pays the gas | None: a function-call key cannot attach one | None | 200 Tgas, the SDK's SPEND_GAS |
anchor on the vault | The ledger key on the vault account. The vault's own NEAR pays the gas | None: a function-call key cannot attach one | None | 30 Tgas, the SDK's ANCHOR_GAS |
expire_held on the vault | Anyone, once the hold has expired | None | Not built by a Probarion tool | Not set by a Probarion tool |
create_vault on the factory | Anyone. The caller becomes the new vault's owner | At least min_deposit, plus the byte cost of the code for an embedded version. Less is InsufficientDeposit. The deposit stays in the vault as its NEAR, and is refunded if the name is taken | The owner's choice, at most 5 NEAR in the console. The CLI attaches min_deposit unless --deposit is given, and needs --deposit for an embedded version | 300 Tgas |
store_code on the factory | The factory owner, from a full-access key | Exactly 1 yoctoNEAR | Not built by a Probarion tool: the factory owner signs it with near-cli-rs | Not set by a Probarion tool |
add_version on the factory | The factory owner, from a full-access key | Exactly 1 yoctoNEAR | Not built by a Probarion tool: the factory owner signs it with near-cli-rs | Not set by a Probarion tool |
publish_global on the factory | The factory owner, from a full-access key | Exactly 1 yoctoNEAR. The factory's own balance pays for the global contract | Not built by a Probarion tool: the factory owner signs it with near-cli-rs | Not set by a Probarion tool |
storage_deposit on the USDC token | The owner, to register the vault on the token before funding it, or the 1Click deposit address of a top-up | Set by the token contract | 0.00125 NEAR, the console's FT_STORAGE_DEPOSIT | 30 Tgas |
ft_transfer on the USDC token | The owner, to fund the vault with USDC, or to pay a 1Click top-up quote | Set by the token contract | 1 yoctoNEAR | 30 Tgas |
Owner signs
The owner signs create_vault, create_mandate, revoke_mandate, add_agent, remove_agent, set_ledger_key, freeze, unfreeze, withdraw and withdraw_intents from their own wallet, and the USDC token calls that fund the vault or pay a top-up. Their wallet pays each call's gas and deposit.
Approver signs
An approver signs approve or reject from their own wallet, with exactly 1 yoctoNEAR, and their wallet pays the gas.
Gas the contracts attach#
When a method calls another contract, the gas for that call comes out of the prepaid gas of the transaction that started it. That is why the calls that reach the USDC token or NEAR Intents prepay more than a plain owner call, and a payout also runs a callback. The 1 yoctoNEAR the vault attaches to a payout comes from the vault's own NEAR.
| Constant | Value | The call it pays for | Deposit attached |
|---|---|---|---|
GAS_FT_TRANSFER, vault | 15 Tgas | ft_transfer on the USDC token: a payout to a NEAR payee, and withdraw | ONE_YOCTO |
GAS_FT_WITHDRAW, vault | 100 Tgas | ft_withdraw on NEAR Intents: a payout to a Base or Solana payee, and withdraw_intents | ONE_YOCTO |
GAS_STORAGE_DEPOSIT, vault | 10 Tgas | storage_deposit on the USDC token for a NEAR payee, from create_mandate. The vault does not wait for its result | USDC_STORAGE_DEPOSIT |
GAS_CALLBACK, vault | 15 Tgas | The payout's callback, on_transfer or on_withdraw, which settles or releases the spend | None |
GAS_VAULT_NEW, factory | 30 Tgas | new on the vault account that create_vault makes | None |
GAS_ON_VAULT_CREATED, factory | 15 Tgas | The callback of create_vault, on_vault_created, which records the vault or refunds the deposit | None |
What a builder pays#
Probarion takes no fee, and there is no price list or paid plan (Pricing). A vault costs NEAR, paid to the network, from three places:
- The owner's wallet pays the gas of every call it signs, the 1 yoctoNEAR most of them attach, the
create_vaultdeposit, each mandate's deposit, and 0.00125 NEAR to register an account on the USDC token when funding the vault or paying a top-up. Thecreate_vaultdeposit is not spent: it becomes the vault's own NEAR, and the vault's storage is staked out of it. A mandate's deposit pays for the mandate's storage and a NEAR payee's USDC registration, and the vault refunds the rest. - An approver's wallet pays the gas of
approveandreject. - The vault's own NEAR pays the gas of every
spendandanchor, since the agent key and the ledger key sign as the vault account. It also pays the storage each spend leaves behind, and the storage of each agent key, the ledger key and each anchor:add_agentandset_ledger_keyattach only 1 yoctoNEAR. Each key's allowance caps the gas that key can burn. The vault has no method to withdraw NEAR, so NEAR sent to it stays there.
When the vault's free NEAR runs out, a spend fails with the chain's LackBalanceForState or NotEnoughBalance, not a PROBARION: code, and a plain NEAR transfer to the vault tops it up (Transaction failures). The console's figures for that NEAR:
| Constant | Value | What it is |
|---|---|---|
STORAGE_BYTE_COST_YOCTO | 0.00001 NEAR a byte | NEAR's storage staking: the NEAR an account keeps locked for each byte it stores |
NEAR_PER_SPEND_YOCTO | 0.0053 NEAR | About what one paid spend costs the vault: the storage it leaves for good and the gas it burns. A failed spend costs less |
EMBEDDED_VAULT_WASM_BYTES | 248,501 bytes | The size of the vault wasm, which an embedded vault stores a copy of |
EMBEDDED_CODE_ESTIMATE_BYTES | 273,352 bytes | What the console counts for that copy, the wasm plus 10 percent: 2.73352 NEAR at the byte cost. What the code does not take stays in the vault |
FRESH_VAULT_STATE_BYTES | 2,232 bytes | What a new vault stores besides its code, for the console's estimate of a new vault's NEAR |
LOW_NEAR_YOCTO | 0.1 NEAR | Below this much free NEAR the console shows the vault's runway in amber |
NEAR_LOW_ALERT_YOCTO | 0.05 NEAR | Below this much free NEAR the watcher records a near_low event, at most once a UTC day |
ALLOWANCE_LOW_ALERT_YOCTO | 0.2 NEAR | Below this much allowance left on an agent or ledger key the watcher records an allowance_low event, at most once a key and UTC day |
MAX_CREATE_DEPOSIT_YOCTO | 5 NEAR | The most the console attaches to create_vault: a taken name is refunded from the factory's own balance |
MAX_TOPUP_YOCTO | 5 NEAR | The most one plain NEAR transfer to the vault sends from the console. NEAR sent to a vault does not come back out |
DEFAULT_TOPUP_YOCTO | 0.5 NEAR | The top-up the console suggests |
The free NEAR is the balance minus the storage stake, amount - storage_usage * 10^19 in yoctoNEAR. near-cli-rs shows both for any vault:
near account view-account-summary v0.probarion.testnet network-config testnet nowKey allowances#
An agent key and the ledger key sign as the vault account, so the gas they burn comes out of the vault's NEAR, up to the key's allowance. A key that has burned its whole allowance can no longer sign, and the owner adds a new key.
| Key | May call | Allowance the console gives it, and the CLI's default | What the vault checks |
|---|---|---|---|
An agent key, added with add_agent | spend on the vault | 1 NEAR: the console's VAULT_DEFAULTS.agentAllowanceYocto and the default of agent add --allowance. For the Canary's vault the console asks for 3 NEAR (CANARY_KEY_ALLOWANCES.agentAllowanceYocto): its raw mode stops when the agent key has under 0.2 NEAR left | An allowance above 0 yoctoNEAR. An allowance of 0, an unlimited key, fails with InvalidInput |
The ledger key, set with set_ledger_key | anchor on the vault | 0.25 NEAR: the console's VAULT_DEFAULTS.ledgerAllowanceYocto and the default of ledger set-key --allowance. For the Canary's vault the console asks for 2 NEAR (CANARY_KEY_ALLOWANCES.ledgerAllowanceYocto): the Canary does not open while the ledger key has under 0.5 NEAR left | An allowance above 0 yoctoNEAR. An allowance of 0, an unlimited key, fails with InvalidInput |
Cross-chain payouts#
Probarion adds no fee to a payout to a Base or Solana payee: the vault sends ft_withdraw the spend's amount, and its code computes no bridge or token fee. On testnet the stand-in for NEAR Intents, intents-stub.probarion.testnet, takes no fee. A fee that NEAR Intents or its bridge may take on mainnet is not modelled in this code, and this page does not cover it. No Base or Solana payout has run on mainnet, because spike S1 is unproven. The one mainnet vault, v0.probarion.near, has paid only a NEAR payee.
Top-ups through 1Click#
The console's top-up is meant to buy a vault's Base USDC balance inside NEAR Intents through 1Click. It is built for mainnet only and has not been tried with a live quote yet. It asks 1Click for the exact amount out with a 1 percent slippage tolerance, and refuses a quote that would cost more than 5 percent over that amount. The owner then pays the quote from their own wallet, with a storage_deposit and an ft_transfer on the USDC token.
Hosted app limits#
The hosted app adds limits of its own: what the Payables upload takes and reads, the mandate form, the top-up, the testnet faucet, alerts, and the browser extension's inbox and invoice queue, whose routes are Preview. During the beta its mandate form is stricter than the vault: the CLI accepts 1 to 4,294,967,295 for --uses, and the contract any expiry in the future.
| Constant | Value | What it is |
|---|---|---|
MAX_INVOICE_BYTES | 4,194,304 bytes (4 MiB) | The largest invoice file, pasted invoice text or purpose document the console's Payables upload takes, and the largest invoice file the browser extension queues. The upload's whole request may be 64 KiB larger, for the form: MAX_REQUEST_BYTES in lib/payables/upload.ts. Past a cap, 413 too_large |
MAX_TEXT_CHARS | 50,000 | The UTF-16 units of invoice text Payables reads, shows the model and hashes: the invoice hash is the hash of exactly that text. Longer text is cut, and its amount is refused |
MAX_PDF_PAGES | 20 | The pages of a PDF invoice Payables reads. The pages past them are not read or hashed, and the amount is refused |
MAX_USES_BETA | 10,000 | The most payments the console's mandate form allows a mandate during the beta. The contract takes any u32 above 0 |
MAX_EXPIRY_AHEAD_MS | 31,622,400,000 ms (366 days) | How far ahead the console's mandate form lets an expiry be, during the beta. The contract asks only for a time in the future |
MIN_EXPIRY_AHEAD_MS | 3,600,000 ms (1 hour) | The earliest expiry the form accepts, counted from now: time for the owner to sign before it passes |
MIN_TOPUP_UNITS | 1,000,000 units (1 USDC) | The least one 1Click top-up asks for. The top-up is built for mainnet only and has not been tried with a live quote yet |
MAX_TOPUP_UNITS | 1,000,000,000 units (1,000 USDC) | The most one 1Click top-up asks for, during the beta |
MIN_LEFT_MS | 60,000 ms (1 minute) | A 1Click quote with less time than this left before its deadline is not offered for signing |
FAUCET_USDC | 25 test USDC | What one use of the testnet faucet mints into the vault. The faucet limiters in the rate limits cap how often |
Active alerts, checked in alert_subscription_create | 20 | The most active alerts one vault may have, email and Telegram together. Past it the console asks the owner to remove one first |
MAX_VAULTS | 10 | The vaults one GET /api/ext/inbox answer covers, of those the account owns or approves on that network |
MAX_ROWS | 10 | The invoices waiting for the owner, and the held payments, that the extension's inbox lists for each vault. Its counts include every one |
MAX_REPORT_BYTES | 2,097,152 bytes (2 MiB) | The most of NEAR AI's attestation report the proof page's live TEE check (GET /api/tee/check) reads. A larger report is not read: the next preferred model is asked when NEARAI_MODEL is unset, else each check is unavailable |
MAX_ATTESTATIONS | 4 | The model attestations of one report that the live TEE check checks, the first ones. Any past them are not checked: the answer's attestations_total counts them, and a pass says it covered the first of them only |
Rate limits#
Each limiter allows the hits shown in its window, for each IP address, account, vault or email address it counts. A route past its limit answers 429 rate_limited with a Retry-After header, and a page or a console action shows a message instead. No window is longer than a day (RATE_LIMIT_KEEP_S), because a daily job deletes older counters. HTTP API lists each route with its callers and errors.
| Limiter | Limit | Counted per | Applies to |
|---|---|---|---|
authChallenge | 20 in a minute | IP address | GET /api/auth/challenge, the start of sign-in |
authVerify | 10 in a minute | IP address | POST /api/auth/verify, the signed sign-in |
snapshot | 30 in a minute | IP address, for each file | GET /proof/<vault>/snapshot.json, GET /proof/<vault>/ledger.jsonl and GET /proof/<vault>/payments.csv |
proofPage | 60 in a minute | IP address | The public proof page, /proof/<vault> |
topupQuote | 10 in a minute | Signed-in account and network | POST /api/topup/quote. The top-up is built for mainnet only and has not been tried with a live quote yet |
topupStatus | 30 in a minute | Signed-in account and network | GET /api/topup/status |
topupSubmit | 10 in a minute | Signed-in account and network | POST /api/topup/submit |
invoiceUpload | 30 in an hour | Vault | POST /api/console/<vault>/invoices, the Payables upload |
canaryModelVisitor | 5 in 10 minutes | IP address | POST /api/canary/attempt, before the model is asked |
canaryModelGlobal | 300 in an hour | All visitors together | POST /api/canary/attempt |
telegramWebhook | 120 in a minute | All calls together | POST /api/telegram/webhook |
alertTest | 5 in 10 minutes | Vault | New alerts, emails and Telegram links on the console's alerts page, together |
alertLink | 30 in a minute | IP address | The email confirmation page /alerts/confirm and POST /api/alerts/confirm |
alertConfirmAddress | 3 in a day | Email address, from every vault together | The confirmation emails the alerts page sends |
confirmPerAccount | 30 in a minute | Signed-in account and network | The console's chain reads for a signed transaction: its confirmation, and the block height read when the send starts, each with its own counters |
confirmGlobal | 300 in a minute | All accounts together | The same reads, each with its own counter |
registerPerAccount | 10 in 10 minutes | Signed-in account and network | Registering an existing vault in the console |
extPairPerIp | 10 in 10 minutes | IP address and network | POST /api/ext/pair, the browser extension's pairing-code exchange |
extPairGlobal | 300 in 10 minutes | All addresses together, per network | POST /api/ext/pair |
extInbox | 60 in a minute | Extension token's account and network | GET /api/ext/inbox |
extInvoice | 20 in 10 minutes | Extension token's account and network | POST /api/ext/invoices: invoices the browser extension queues for the owner's Confirm |
extMint | 10 in 10 minutes | Signed-in account and network | Tokens and pairing codes the extension page makes, together |
faucetVault | 1 in a day | Vault, each UTC day | POST /api/topup/faucet, the test USDC faucet on testnet |
faucetAccount | 3 in a day | Signed-in owner account, each UTC day | POST /api/topup/faucet, the same faucet |
faucetGlobal | 50 in a day | All vaults together, each UTC day | POST /api/topup/faucet, the same faucet |
faucetTries | 10 in 10 minutes | Signed-in account | POST /api/topup/faucet: each press of the faucet button, before the chain is read |
teeCheck | 30 in a minute | All visitors together | GET /api/tee/check, the proof page's live TEE check |
SDK and core limits#
These bound what @probarion/sdk and @probarion/core send, keep and wait for.
| Constant | Package | Value | What it is |
|---|---|---|---|
USDC_DECIMALS | @probarion/core | 6 | Amounts travel in USDC's base units, so 1 USDC is 1000000 |
PAGE_SIZE | @probarion/sdk | 50 | Items the SDK asks for in each page when it reads a whole list |
MAX_PAGE_LIMIT | @probarion/sdk | 100 | The largest limit the SDK sends: the contracts' MAX_PAGE |
MAX_RESPONSE_BODY_BYTES | @probarion/sdk | 65,536 bytes (64 KiB) | The largest NEAR AI response the SDK uses. The response goes into the ledger entry |
CATALOG_PAGE_SIZE | @probarion/sdk | 100 | Models the SDK asks NEAR AI's model catalog for in each page |
DEFAULT_NEARAI_TIMEOUTS_MS | @probarion/sdk | catalog 10,000 ms (10 seconds), report 15,000 ms (15 seconds), chat 90,000 ms (90 seconds), signature 15,000 ms (15 seconds) | How long each kind of NEAR AI call may take, headers and body together, before the SDK gives up on it. The timeoutMs option overrides it per kind |
PROPOSAL_MAX_TOKENS | @probarion/core | 4,096 | The max_tokens of a decision request to the model |
MAX_REASONING_CHARS | @probarion/core | 2,000 | The model's reasoning is cut to this many Unicode code points |
UNKNOWN_SETTLE_MS | @probarion/sdk | 172,800,000 ms (48 hours) | How long code refuses an invoice whose spend has an unknown outcome, unless the chain shows the spend sooner |
What the tables leave out#
- The limits an owner sets for each payment and for the vault's day: Mandates and How a payment is checked.
- The arguments, return values and errors of each method: Contract reference.
- The body, callers and errors of each route: HTTP API.
- The Canary's own caps on
POST /api/canary/attempt, inCANARY_LIMITS(apps/web/src/lib/canary/limits.ts): attempts from one address and from everyone in an hour and a day, a daily budget of model tokens, the length of a message, and how often an attempt may go on chain. An attempt past an attempt cap or the token budget gets429 budget, notrate_limited. - Caps the hosted app keeps on its own work and display, such as how far behind a node the health check accepts and how much of a ledger string the proof page shows.
- The NEAR protocol's own limits, such as the most gas one transaction may carry, and the price of gas.
- Mainnet values. The code is the same on both networks, but the mainnet factory is not deployed, and no mainnet
min_depositis recorded. The one mainnet vault,v0.probarion.near, was deployed without a factory. Testnet and mainnet explains the difference.
Related pages#
- Vaults, roles and keys: who holds which key, and the allowance on each function-call key.
- Holds and approvals: what
approvepays out, and when a hold expires. - Errors: every code the tables name.
- Contract reference: every method of the vault and the factory.
- The sources:
contracts/vault/src/lib.rs(opens in a new tab),contracts/factory/src/lib.rs(opens in a new tab),apps/web/src/lib/near/runway.ts(opens in a new tab) andapps/web/src/lib/ratelimit.ts(opens in a new tab).
Built from 4ab41ca · reviewed
contracts/vault/src/lib.rs(opens in a new tab)contracts/vault/src/validate.rs(opens in a new tab)contracts/vault/src/admin.rs(opens in a new tab)contracts/vault/src/mandates.rs(opens in a new tab)contracts/vault/src/keys.rs(opens in a new tab)contracts/vault/src/held.rs(opens in a new tab)contracts/vault/src/spend.rs(opens in a new tab)contracts/vault/src/anchors.rs(opens in a new tab)contracts/vault/src/checks.rs(opens in a new tab)contracts/vault/src/ext.rs(opens in a new tab)contracts/vault/src/errors.rs(opens in a new tab)contracts/vault/src/types.rs(opens in a new tab)contracts/factory/src/lib.rs(opens in a new tab)contracts/deployments/testnet.json(opens in a new tab)contracts/deployments/mainnet.json(opens in a new tab)contracts/intents-stub/src/lib.rs(opens in a new tab)packages/core/src/constants.ts(opens in a new tab)packages/core/src/proposal.ts(opens in a new tab)packages/core/src/proposal-request.ts(opens in a new tab)packages/core/src/policy.ts(opens in a new tab)packages/sdk/src/index.ts(opens in a new tab)packages/sdk/src/vault-client.ts(opens in a new tab)packages/sdk/src/paging.ts(opens in a new tab)packages/sdk/src/nearai.ts(opens in a new tab)packages/sdk/src/ledger-store.ts(opens in a new tab)packages/sdk/src/ledger-store-lock.ts(opens in a new tab)packages/sdk/src/spend-outcome.ts(opens in a new tab)packages/sdk/src/tx.ts(opens in a new tab)packages/cli/src/commands/owner-calls.ts(opens in a new tab)packages/cli/src/commands/mandate.ts(opens in a new tab)packages/cli/src/commands/vault.ts(opens in a new tab)packages/cli/src/commands/agent.ts(opens in a new tab)packages/cli/src/commands/ledger.ts(opens in a new tab)packages/cli/src/units.ts(opens in a new tab)packages/cli/src/payee.ts(opens in a new tab)apps/web/src/lib/config.ts(opens in a new tab)apps/web/src/lib/http.ts(opens in a new tab)apps/web/src/lib/near/tx.ts(opens in a new tab)apps/web/src/lib/near/runway.ts(opens in a new tab)apps/web/src/lib/near/confirm-action.ts(opens in a new tab)apps/web/src/lib/ratelimit.ts(opens in a new tab)apps/web/src/lib/payables/limits.ts(opens in a new tab)apps/web/src/lib/payables/extract.ts(opens in a new tab)apps/web/src/lib/payables/upload.ts(opens in a new tab)apps/web/src/lib/payables/amount.ts(opens in a new tab)apps/web/src/lib/console/mandates.ts(opens in a new tab)apps/web/src/lib/console/vaults.ts(opens in a new tab)apps/web/src/lib/topup/oneclick.ts(opens in a new tab)apps/web/src/lib/topup/gate.ts(opens in a new tab)apps/web/src/lib/topup/faucet.ts(opens in a new tab)apps/web/src/lib/topup/amount.ts(opens in a new tab)apps/web/src/lib/topup/block.ts(opens in a new tab)apps/web/src/lib/ext/inbox.ts(opens in a new tab)apps/web/src/lib/canary/limits.ts(opens in a new tab)apps/web/src/lib/canary/service.ts(opens in a new tab)apps/web/src/lib/docs/errors.ts(opens in a new tab)apps/web/src/lib/health.ts(opens in a new tab)apps/web/src/lib/proof/sanitize.ts(opens in a new tab)apps/web/supabase/migrations/20261108000011_alerts.sql(opens in a new tab)apps/web/src/app/api/console/[vault]/invoices/route.ts(opens in a new tab)apps/web/src/app/api/auth/challenge/route.ts(opens in a new tab)apps/web/src/app/api/auth/verify/route.ts(opens in a new tab)apps/web/src/app/proof/[vault]/page.tsx(opens in a new tab)apps/web/src/app/proof/[vault]/snapshot.json/route.ts(opens in a new tab)apps/web/src/app/proof/[vault]/ledger.jsonl/route.ts(opens in a new tab)apps/web/src/app/proof/[vault]/payments.csv/route.ts(opens in a new tab)apps/web/src/app/api/topup/quote/route.ts(opens in a new tab)apps/web/src/app/api/topup/status/route.ts(opens in a new tab)apps/web/src/app/api/topup/submit/route.ts(opens in a new tab)apps/web/src/app/api/topup/faucet/route.ts(opens in a new tab)apps/web/src/app/api/canary/attempt/route.ts(opens in a new tab)apps/web/src/app/api/telegram/webhook/route.ts(opens in a new tab)apps/web/src/app/api/alerts/confirm/route.ts(opens in a new tab)apps/web/src/app/alerts/confirm/page.tsx(opens in a new tab)apps/web/src/app/console/[vault]/alerts/actions.ts(opens in a new tab)apps/web/src/app/console/[vault]/keys/actions.ts(opens in a new tab)apps/web/src/app/console/actions.ts(opens in a new tab)apps/web/src/app/api/ext/pair/route.ts(opens in a new tab)apps/web/src/app/api/ext/inbox/route.ts(opens in a new tab)apps/web/src/app/api/ext/invoices/route.ts(opens in a new tab)apps/web/src/app/extension/actions.ts(opens in a new tab)docs/runbooks/testnet.md(opens in a new tab)docs/runbooks/factory.md(opens in a new tab)docs/THREAT_MODEL.md(opens in a new tab)docs/evidence/mainnet-v0/README.md(opens in a new tab)