otto-execute 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The user's side of Otto's execution seam. [Otto Intel MCP](https://www.npmjs.com/package/otto-intel-mcp) builds a swap as an unsigned, digest-committed **envelope** for an address you supply; `otto-execute` checks that envelope against **your own intent**, then signs and submits it with **your** key (or under a delegation you minted). CLI and library, one install.
4
4
 
5
- - npm: `npm install otto-execute` — 18 packages (`@x402/core`, `@x402/evm`, `viem`, `zod`).
5
+ - npm: `npm install otto-execute` — 19 packages including itself (`@x402/core`, `@x402/evm`, `viem`, `zod`), 0 `npm audit` findings.
6
6
  - Docs: https://docs.useotto.xyz/acp-swarm/execution-seam
7
7
  - Requires Node 22 or newer.
8
8
 
@@ -25,7 +25,7 @@ The user's side of Otto's execution seam. [Otto Intel MCP](https://www.npmjs.com
25
25
  }
26
26
  ```
27
27
 
28
- Any MCP client works (connection snippets: the [otto-intel-mcp README](https://www.npmjs.com/package/otto-intel-mcp)); the tool result is one text part containing JSON — save that JSON object (it starts with `schema_version`, `artifact_id`, …) as `envelope.json`. It is valid for 10 minutes. v1 builds Base (chain 8453) swaps.
28
+ Any MCP client works (connection snippets: the [otto-intel-mcp README](https://www.npmjs.com/package/otto-intel-mcp)); the tool result is one text part containing JSON — save that JSON object (it starts with `schema_version`, `artifact_id`, …) as `envelope.json`. It is valid for **5 minutes** from construction (`valid_until`; the hosted server's window — the tool description states it), and `submit` re-checks freshness before each of its three signatures, so don't pace on the window: verify, then submit, or fetch a fresh envelope. v1 builds Base (chain 8453) swaps.
29
29
 
30
30
  **2. Write your intent** — what *you* meant, in atomic token units (USDC has 6 decimals: `1000000` = 1 USDC; WETH has 18: `200000000000000` = 0.0002 WETH). `minAmountOut` is your own floor from a price source you trust:
31
31
 
@@ -58,11 +58,14 @@ OTTO_EXECUTE_PRIVATE_KEY=0x… npx otto-execute submit --envelope envelope.json
58
58
  { "recipient": "0x0E84dDEdAaE6A779c462C22a59F301EC31B6b808", "amount": "1000" }
59
59
  ],
60
60
  "valid_until": "2026-09-02T09:00:49.613Z",
61
+ "seconds_remaining": 287,
61
62
  "artifact_id": "01M1GN9T3DH6470V0Y8968QXRX"
62
63
  }
63
64
  }
64
65
  ```
65
66
 
67
+ `seconds_remaining` is the budget you have left to `submit` (the whole plan must clear before `valid_until`).
68
+
66
69
  A plan that does not hold is refused by name, exit code 2 — for example an envelope past its window:
67
70
 
68
71
  ```json
@@ -131,4 +134,4 @@ Working in the monorepo: `npm ci && npm run verify` (typecheck → build incl. v
131
134
  - Execution seam docs (the envelope field by field, the checks, delegation): https://docs.useotto.xyz/acp-swarm/execution-seam
132
135
  - Otto Intel MCP (the constructors + intelligence tools): https://www.npmjs.com/package/otto-intel-mcp · https://docs.useotto.xyz/acp-swarm/otto-intel-mcp
133
136
  - Otto AI: https://useotto.xyz · X: [@useOttoAI](https://x.com/useOttoAI)
134
- - Changelog: 0.1.1 — README rewritten for first-time users and agents (quick start, captured real output, file shapes); 0.1.0 — first release.
137
+ - Changelog: 0.1.2 — `verify` prints `seconds_remaining` (the submit budget) and `secondsRemaining()` is exported; envelope window documented as 5 minutes; 0.1.1 — README rewritten for first-time users and agents (quick start, captured real output, file shapes); 0.1.0 — first release.
package/dist/cli.js CHANGED
@@ -18,6 +18,7 @@ import { readFileSync } from 'node:fs';
18
18
  import { createInterface } from 'node:readline';
19
19
  import { getAddress } from 'viem';
20
20
  import { privateKeyToAccount } from 'viem/accounts';
21
+ import { secondsRemaining } from './window.js';
21
22
  import { DEFAULT_OTTO_MCP_URL, DelegateRefusal, UNSUPPORTED_PATH_NOTE, assertFencePresent, initEndUserSdk, isDelegateRefusal, mintDelegation, readDelegationAsUser, readPublicFenceStatus, redactSecrets, resolveDelegateEndpoints, revokeDelegationAsUser, signInWithEmailOtp, } from './delegate.js';
22
23
  import { EoaSigner } from './eoa-signer.js';
23
24
  import { isAdapterRefusal } from './refusal.js';
@@ -381,6 +382,8 @@ async function main() {
381
382
  min_amount_out: verified.minAmountOut,
382
383
  fee_distributions: verified.fees.distributions,
383
384
  valid_until: verified.artifact.valid_until,
385
+ // The budget left to submit the WHOLE plan (freshness is re-checked before every signature).
386
+ seconds_remaining: secondsRemaining(verified.artifact.valid_until),
384
387
  artifact_id: verified.artifact.artifact_id,
385
388
  };
386
389
  if (command === 'verify') {
package/dist/index.d.ts CHANGED
@@ -14,3 +14,4 @@ export { waitForSealedReceipt, type SealedClient, type SealedWaitOptions } from
14
14
  export { EOA_CAPABILITIES, EoaSigner, PlanHaltedError, type DryRunSignedStep, type SentStep, type SignedX402Payment, } from './eoa-signer.js';
15
15
  export { BASE_USDC, OTTO_X402_PAY_TO, X402_REFUSAL_CODES, X402_TABLE, X402_TABLE_VERSION, X402Refusal, canonicalResourceUrl, requirementMatchesRow, validateX402Challenge, type PaymentRequirementLike, type ValidatedX402Challenge, type X402ExpectedRow, type X402RefusalCode, type X402Table, } from './x402-table.js';
16
16
  export { FOREIGN_ADDRESS, FOREIGN_TOKEN, MUTATION_CASES, applyMutation, recommit, recommitCommitmentOnly, recommitPayloadOnly, type CatchingLayer, type MutationCase, type MutationContext, } from './mutations.js';
17
+ export { secondsRemaining } from './window.js';
package/dist/index.js CHANGED
@@ -16,4 +16,5 @@ export { EOA_CAPABILITIES, EoaSigner, PlanHaltedError, } from './eoa-signer.js';
16
16
  // optional `@coinbase/cdp-sdk` peer (loaded lazily); this root never references the SDK at all.
17
17
  export { BASE_USDC, OTTO_X402_PAY_TO, X402_REFUSAL_CODES, X402_TABLE, X402_TABLE_VERSION, X402Refusal, canonicalResourceUrl, requirementMatchesRow, validateX402Challenge, } from './x402-table.js';
18
18
  export { FOREIGN_ADDRESS, FOREIGN_TOKEN, MUTATION_CASES, applyMutation, recommit, recommitCommitmentOnly, recommitPayloadOnly, } from './mutations.js';
19
+ export { secondsRemaining } from './window.js';
19
20
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * window.ts — the freshness budget a caller has left on an envelope. The constructor stamps
3
+ * `valid_until` (5 minutes from construction on the hosted server by default; the tool description
4
+ * states the exact window) and the verifier and both signers refuse a stale envelope before every
5
+ * signature — so the WHOLE plan (allowance reset → approval → swap, each waited to a sealed block)
6
+ * must clear before `valid_until`. `verify` prints this so a user sees the budget instead of
7
+ * discovering it as STALE_ARTIFACT mid-plan.
8
+ */
9
+ /** Whole seconds until `validUntil` (an ISO-8601 instant), never negative; `NaN` in → 0. */
10
+ export declare function secondsRemaining(validUntil: string, nowMs?: number): number;
package/dist/window.js ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * window.ts — the freshness budget a caller has left on an envelope. The constructor stamps
3
+ * `valid_until` (5 minutes from construction on the hosted server by default; the tool description
4
+ * states the exact window) and the verifier and both signers refuse a stale envelope before every
5
+ * signature — so the WHOLE plan (allowance reset → approval → swap, each waited to a sealed block)
6
+ * must clear before `valid_until`. `verify` prints this so a user sees the budget instead of
7
+ * discovering it as STALE_ARTIFACT mid-plan.
8
+ */
9
+ /** Whole seconds until `validUntil` (an ISO-8601 instant), never negative; `NaN` in → 0. */
10
+ export function secondsRemaining(validUntil, nowMs = Date.now()) {
11
+ const until = Date.parse(validUntil);
12
+ if (!Number.isFinite(until))
13
+ return 0;
14
+ return Math.max(0, Math.floor((until - nowMs) / 1000));
15
+ }
16
+ //# sourceMappingURL=window.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "otto-execute",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "The user's side of Otto Model B: verify a prepare-only execution artifact from the Otto Intel MCP against your own intent and the ruled attribution, then sign and submit it with your own key (or under a delegation you minted). Otto never holds your keys or funds.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://docs.useotto.xyz",