@defdone/annon 0.1.0-alpha.1 → 0.1.0-alpha.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/CHANGELOG.md +8 -0
- package/CLI.md +116 -10
- package/README.md +41 -9
- package/dist/api/annon-types.d.ts +2 -1
- package/dist/api/annon.js +9 -2
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/login-bundle.js +61 -60
- package/dist/browser/login-dom.d.ts +13 -0
- package/dist/browser/login-dom.js +67 -0
- package/dist/browser/login-dropdown.d.ts +32 -0
- package/dist/browser/login-dropdown.js +129 -0
- package/dist/browser/login-format.d.ts +16 -0
- package/dist/browser/login-format.js +52 -0
- package/dist/browser/login-status.d.ts +70 -0
- package/dist/browser/login-status.js +85 -0
- package/dist/browser/login-terms.d.ts +10 -0
- package/dist/browser/login-terms.js +69 -0
- package/dist/browser/login-view.d.ts +34 -0
- package/dist/browser/login-view.js +227 -0
- package/dist/browser/login-wallet.d.ts +28 -0
- package/dist/browser/login-wallet.js +179 -0
- package/dist/browser/login.js +115 -140
- package/dist/browser/purchase-bundle.js +29 -29
- package/dist/browser/purchases.d.ts +4 -0
- package/dist/browser/purchases.js +14 -0
- package/dist/browser/reconcile.d.ts +41 -0
- package/dist/browser/reconcile.js +77 -0
- package/dist/node/adapter.js +5 -2
- package/dist/node/approval-status.d.ts +34 -0
- package/dist/node/approval-status.js +71 -0
- package/dist/node/backup-secret-init.d.ts +9 -0
- package/dist/node/backup-secret-init.js +103 -0
- package/dist/node/backup-secret.d.ts +35 -0
- package/dist/node/backup-secret.js +104 -0
- package/dist/node/browser-login.d.ts +2 -0
- package/dist/node/browser-login.js +67 -13
- package/dist/node/buy-commands.js +9 -2
- package/dist/node/cli.js +23 -7
- package/dist/node/command-context.js +1 -1
- package/dist/node/config.d.ts +2 -0
- package/dist/node/config.js +3 -1
- package/dist/node/login-page.d.ts +7 -0
- package/dist/node/login-page.js +71 -0
- package/dist/node/purchase-commands.d.ts +2 -2
- package/dist/node/purchase-commands.js +10 -6
- package/dist/node/saved-state.d.ts +4 -0
- package/dist/node/saved-state.js +50 -0
- package/dist/node/version.d.ts +1 -0
- package/dist/node/version.js +3 -0
- package/dist/node/wallets.d.ts +1 -1
- package/dist/node/wallets.js +2 -10
- package/dist/pay/purchase.d.ts +2 -1
- package/dist/wallet/uncertain.d.ts +6 -3
- package/dist/wallet/uncertain.js +4 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @defdone/annon
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Add `BrowserPurchaseController.reconcile()` so a purchase that 1Click reported as failed can be checked again. Under the purchase lease it keeps the same purchase, deposit and recovery identity, checks NEAR acceptance and reads the existing deposit's 1Click status once. Accepted moves to `accepted`, `SUCCESS` to `accepting` and `REFUNDED` to `refunded`; anything else stays `failed` with the new status saved. If the saved deposit address or memo, the restored purchase's deposit and the saved polling checkpoint disagree, it refuses before any read or write. It never creates, starts or pays for a purchase.
|
|
8
|
+
- Bare `annon init` creates the CLI backup secret at `~/.config/annon/backup-secret`: 32 random bytes as hex, mode 0600 from the first write, published with a hard link so it never appears half-written and never replaces an existing file. Running it again only validates the file. It refuses to create a new secret while saved records or backups exist, never prints the secret, and sends its one-time notice to stderr. `--backup-secret-file`, `ANNON_BACKUP_SECRET_FILE` and `ANNON_BACKUP_SECRET` keep their precedence; the default file is read only when none is set, and a selected source that fails never falls back. Other commands, agent mode and MCP read the default but never create it. Reading the default checks that `~/.config/annon` is a private directory you own, refuses symlinks, FIFOs and other non-regular files without blocking, and never repairs anything. Bare `init` reports an unreadable config as a setup error (exit 2). A pending `status` now uses the default file too. `annon --version` (or `-v`) prints the installed version. The quickstart replaces the manual secret recipe with `annon init` and explains backup and restore.
|
|
9
|
+
- The CLI wallet approval page shows a readable summary of exactly what the wallet signs: a title per action, the pairing code to compare, amounts in USDC or NEAR, receiver, account, expiry and what signing does, with the CLI's terms shown apart and the raw request under Technical details (the NEP-413 nonce as hex). Each click opens at most one wallet window, so Meteor's web popup is no longer blocked: NEP-413 messages are signed without a sign-in, and transactions connect first and then send. After a closed, blocked or declined wallet window the page explains it and allows another try until the request expires. The terminal prints a waiting line with the expiry, the reported wallet failure and a specific final error (`cancelled`, `rejected` or `wallet_error`) instead of `operation_failed`. Once the page has called the wallet's send for a transaction, the request is never attempted again: the CLI records the send start before the wallet is called, the request ends as `transaction_uncertain` with a warning not to pay again, the saved purchase keeps that state without inventing a transaction hash, and it blocks a plain rerun of `annon buy` until it is accepted or `--force` is used. A result the CLI cannot verify after the send start also ends as uncertain, keeping a valid transaction hash when there is one. An uncertain `annon buy` exits 4, and `annon status` reports `submission: "uncertain"` with a warning not to pay again. The NEAR wallet is chosen in a styled, keyboard-accessible list instead of the browser's native menu.
|
|
10
|
+
|
|
3
11
|
## 0.1.0-alpha.1
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/CLI.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Build with `pnpm build`. The `@defdone/annon` package ships the `annon` bin;
|
|
4
4
|
in this checkout run `node packages/annon/dist/node/main.js` in its place.
|
|
5
|
-
Run `annon --help` for all flags
|
|
5
|
+
Run `annon --help` for all flags and `annon --version` (or `-v`) for the installed version; with
|
|
6
|
+
`--json` the version is `{ "ok": true, "result": { "version": ... } }`. It loads no config, wallet
|
|
7
|
+
or secret and also works in agent mode. All commands return JSON; `--json` uses one compact
|
|
6
8
|
JSON line and disables interactive prompts. Success is `{ "ok": true, "result": ... }`;
|
|
7
9
|
errors are `{ "ok": false, "error": { "code": ..., "message": ... } }`.
|
|
8
10
|
|
|
@@ -53,10 +55,9 @@ On macOS, with no NEAR file or credential env value, explicitly select both
|
|
|
53
55
|
service `near-mainnet-alice.near`, account `alice.near:ed25519:PUBLIC_KEY`.
|
|
54
56
|
Other platforms use the credential JSON file or environment. No keychain enumeration occurs.
|
|
55
57
|
|
|
56
|
-
Sell, buy, open, recover and stop also require a
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
generator and keep it outside the repository. It is never derived from a wallet signature.
|
|
58
|
+
Sell, buy, open, recover and stop also require a random 32-byte backup secret. It encrypts the
|
|
59
|
+
local purchase, recovery and sell records and the portable backups. It is never derived from a
|
|
60
|
+
wallet signature or key. See [Backup secret](#backup-secret).
|
|
60
61
|
`verify` and accepted/read-only `status` need neither a wallet nor this secret. A pending Base `status` with saved state and a backup secret may send `unlock` through the configured relayer or NEAR wallet. Status can update encrypted local state and backups: expired/canceled Base payments are marked with `paymentState`, preserving the purchase, attempts and recovery key. It never deletes the purchase record.
|
|
61
62
|
|
|
62
63
|
State directories are created with mode 0700 and records/outputs with 0600. Keep existing
|
|
@@ -64,8 +65,99 @@ state directories private. Purchases and recovery grants are encrypted by the SD
|
|
|
64
65
|
encrypted backups are under `stateDir/backups`. Public headers and resource URLs are saved
|
|
65
66
|
separately for later downloading. Preserve state after timeouts. Losing local state does not
|
|
66
67
|
lose recovery rights: the same recovery wallet can create a fresh grant on a new device with
|
|
67
|
-
a new backup secret
|
|
68
|
-
returned in CLI/MCP results. Plaintext is written only to the explicitly named output.
|
|
68
|
+
a new backup secret ([Loss](#backup-secret) explains when `init` creates one). Keys, signed payment
|
|
69
|
+
payloads and decrypted file contents are never returned in CLI/MCP results. Plaintext is written only to the explicitly named output.
|
|
70
|
+
|
|
71
|
+
### Backup secret
|
|
72
|
+
|
|
73
|
+
Run `annon init` once, before buying, selling or enabling agent mode. It creates
|
|
74
|
+
`~/.config/annon/backup-secret`: 32 random bytes as 64 lowercase hex characters and a newline,
|
|
75
|
+
mode 0600, in a directory created with mode 0700. The file is written to an exclusive temporary
|
|
76
|
+
file and published with a hard link, so it never appears half-written and an existing file is
|
|
77
|
+
never replaced. Running `init` again only validates the file and reports `"created": false`. An
|
|
78
|
+
unsafe default is refused and never repaired: a symlink, FIFO or other non-regular file, a file not
|
|
79
|
+
owned by you or with group or other permission bits, malformed content, or an `~/.config/annon`
|
|
80
|
+
that is a symlink, is not owned by you, or is writable by group or others. An existing 0755
|
|
81
|
+
directory is fine. Every command that reads the default applies the same checks.
|
|
82
|
+
|
|
83
|
+
The location is fixed. `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `XDG_STATE_HOME`, `--config`,
|
|
84
|
+
`ANNON_CONFIG` and `--state-dir` do not move it. For another private location, name an existing file with the explicit inputs below.
|
|
85
|
+
|
|
86
|
+
Sources, in order, as before this file existed:
|
|
87
|
+
|
|
88
|
+
1. `--backup-secret-file` (or, when the flag is absent, `ANNON_BACKUP_SECRET_FILE`), a file with the
|
|
89
|
+
64 hex characters.
|
|
90
|
+
2. `ANNON_BACKUP_SECRET`, the hex value itself. Prefer a file: environment values are inherited by
|
|
91
|
+
child processes.
|
|
92
|
+
3. The default file, only when neither is set.
|
|
93
|
+
|
|
94
|
+
An empty value counts as unset, as before: an empty `--backup-secret-file` selects no file even when
|
|
95
|
+
`ANNON_BACKUP_SECRET_FILE` is set, and moves on to `ANNON_BACKUP_SECRET`. Hex must be lowercase in
|
|
96
|
+
every source; an optional `0x` prefix and surrounding whitespace are accepted. A selected source that is missing,
|
|
97
|
+
unreadable or malformed fails with `backup_secret_required` (exit 2); there is no fallback to a
|
|
98
|
+
later source, the default file or a new secret. `annon init` with an explicit source only validates
|
|
99
|
+
it and never writes, creates or changes that file. Commands other than `init` read the secret but
|
|
100
|
+
never create it, and agent mode and MCP never create it. Bare `init` accepts only `--json`,
|
|
101
|
+
`--config`, `--state-dir` and `--backup-secret-file`; signer options need `--agent`.
|
|
102
|
+
|
|
103
|
+
Output: stdout carries the usual single JSON result, for example
|
|
104
|
+
`{"ok":true,"result":{"configured":true,"backupSecret":{"source":"default-file","path":"/home/me/.config/annon/backup-secret","created":true}}}`.
|
|
105
|
+
`source` is `default-file`, `flag-file`, `env-file` or `env`; `path` is shown for files only. The
|
|
106
|
+
one-time creation notice goes to stderr, also with `--json`. The secret itself is never printed, in
|
|
107
|
+
results, errors or notices.
|
|
108
|
+
|
|
109
|
+
**Back it up.** The secret is not part of the encrypted backups in `stateDir/backups`; copy the file
|
|
110
|
+
itself, separately, to private encrypted storage. Never `cat` it or paste it into a terminal. This
|
|
111
|
+
copies without displaying it and refuses an existing destination:
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
node --input-type=module -e '
|
|
115
|
+
import { constants } from "node:fs";
|
|
116
|
+
import { copyFile } from "node:fs/promises";
|
|
117
|
+
await copyFile(process.argv[1], process.argv[2], constants.COPYFILE_EXCL);
|
|
118
|
+
' "$HOME/.config/annon/backup-secret" /mounted-private-encrypted-backup/annon-backup-secret
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The copy keeps mode 0600 when the destination supports POSIX permissions; check it. A secret manager
|
|
122
|
+
that imports files is also fine.
|
|
123
|
+
|
|
124
|
+
**Restore.** On a new machine, put the saved file in a private directory (directory mode 0700, file
|
|
125
|
+
mode 0600), copy the encrypted record backups separately, and select the file. Do not run `init`
|
|
126
|
+
first:
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
export ANNON_BACKUP_SECRET_FILE=/absolute/private/restored-annon-backup-secret
|
|
130
|
+
annon open /absolute/private/purchase-backup.json --url https://host.example/file --output restored-file
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Opening one known backup proves the restore. To restore to the default location instead, create
|
|
134
|
+
`~/.config/annon` with mode 0700 and copy in the other direction, still refusing an existing file:
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
mkdir -p -m 700 "$HOME/.config/annon"
|
|
138
|
+
node --input-type=module -e '
|
|
139
|
+
import { constants } from "node:fs";
|
|
140
|
+
import { copyFile } from "node:fs/promises";
|
|
141
|
+
await copyFile(process.argv[1], process.argv[2], constants.COPYFILE_EXCL);
|
|
142
|
+
' /mounted-private-encrypted-backup/annon-backup-secret "$HOME/.config/annon/backup-secret"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Loss.** If the secret disappears, commands fail with `backup_secret_required` and a pending
|
|
146
|
+
`status` stays pending; nothing recreates it. Restore the same bytes. Bare `init` creates a new
|
|
147
|
+
secret only when both checked state locations are empty: the effective state directory and the
|
|
148
|
+
default `~/.local/share/annon`, each in `records` and `backups`. If every copy is lost and you want
|
|
149
|
+
to recover with a new secret, first move the whole old state, including `~/.local/share/annon`, to
|
|
150
|
+
a separate private archive and keep it. Then use an empty state directory, run `init`, and run
|
|
151
|
+
`recover` with the same recovery wallet. That creates a fresh grant and new records; it cannot
|
|
152
|
+
decrypt the archived records or resume pending sell jobs. An operator can instead provision a
|
|
153
|
+
separate secret file and select it with `ANNON_BACKUP_SECRET_FILE`. Use one secret per state
|
|
154
|
+
directory.
|
|
155
|
+
|
|
156
|
+
**Agents.** `init --agent` does not create or reference a backup secret. Run bare `init` before it,
|
|
157
|
+
or give the agent an operator-managed file with an absolute `ANNON_BACKUP_SECRET_FILE` in the
|
|
158
|
+
launcher. A launcher that sets `ANNON_BACKUP_SECRET_FILE` must point it at a file that exists; a
|
|
159
|
+
missing file fails without falling back to the default. Once agent mode is active, `init` is
|
|
160
|
+
refused, so provision or restore the secret outside the running agent.
|
|
69
161
|
|
|
70
162
|
## Commands
|
|
71
163
|
|
|
@@ -161,9 +253,23 @@ blindly retried. Raw upstream errors are intentionally suppressed to avoid leaki
|
|
|
161
253
|
| --- | --- |
|
|
162
254
|
| 0 | Command completed; buy may still require a deposit or settlement |
|
|
163
255
|
| 1 | Operation failed; inspect final status and retained encrypted state before retrying |
|
|
164
|
-
| 2 | Invalid arguments, configuration, wallet source or missing local input |
|
|
165
|
-
| 3 | First-use contract trust required or declined |
|
|
166
|
-
| 4 | `status` reports pending;
|
|
256
|
+
| 2 | Invalid arguments, configuration, wallet source or missing local input; `purchase_open` when a saved purchase of the file, including an uncertain NEAR send, still blocks a new one |
|
|
257
|
+
| 3 | First-use contract trust required or declined; browser approval cancelled (`cancelled`), expired (`cancelled`, or `rejected` or `wallet_error` after the last wallet failure the page reported) or declined by the wallet |
|
|
258
|
+
| 4 | Not settled, and not proof of failure: `status` reports pending; `buy` returned `state: "uncertain"` (its payment may be on chain; the JSON result is unchanged and names the saved purchase); or `transaction_uncertain`: a transaction may have been sent and is not confirmed |
|
|
259
|
+
|
|
260
|
+
In browser approval, once the CLI has acknowledged the page's send start, the request can only end
|
|
261
|
+
as a verified transaction or as `transaction_uncertain`: a wallet failure, a cancel, the expiry, or a
|
|
262
|
+
result the CLI cannot verify (an RPC rejection, malformed evidence) never counts as "not sent". The
|
|
263
|
+
purchase is saved with that uncertainty, with the transaction hash only when the wallet returned a
|
|
264
|
+
valid one. `annon buy` then exits 4 with `state: "uncertain"`, and `annon status <purchase id>`
|
|
265
|
+
answers `submission: "uncertain"` until the purchase is accepted. Do not pay again.
|
|
266
|
+
|
|
267
|
+
A plain `annon buy` of the same file is refused with `purchase_open` while that uncertainty is
|
|
268
|
+
saved, also after the purchase expired: a late transfer still moves tokens, and the contract then
|
|
269
|
+
owes a refund that is paid out later rather than returned at once. Neither a pending status, an
|
|
270
|
+
expired purchase nor an empty wallet history proves that nothing was sent. `--force` overrides the
|
|
271
|
+
guard; use it only after you have reconciled the original attempt, for example by finding its
|
|
272
|
+
final transaction or its refund, because otherwise you may pay twice.
|
|
167
273
|
|
|
168
274
|
## SDK seller resume and CKD configuration
|
|
169
275
|
|
package/README.md
CHANGED
|
@@ -203,6 +203,7 @@ const { meta, data } = await controller.open({ onProgress: renderDownload });
|
|
|
203
203
|
before an expired key is replaced. Portable receipts carry those archives too.
|
|
204
204
|
- The local random backup secret is persisted in IndexedDB for reload recovery. It protects
|
|
205
205
|
encrypted storage from accidental disclosure and shares the embedding page's trust boundary.
|
|
206
|
+
This is the browser's secret; the CLI keeps its own in a file ([CLI.md](CLI.md#backup-secret)).
|
|
206
207
|
- Export with `controller.exportReceipt(portableSecret)`, using a separate random 32-byte
|
|
207
208
|
`newBackupSecret()` that you keep separately. Import with
|
|
208
209
|
`storage.importReceipt(file, portableSecret)`. Import restores the header, resource URL and
|
|
@@ -295,6 +296,9 @@ shop-provided data: on each shop's `info` from `listShops`, and as `rules` with
|
|
|
295
296
|
|
|
296
297
|
## CLI browser wallet login
|
|
297
298
|
|
|
299
|
+
Run `annon init` once first. It creates the CLI backup secret file that encrypts local records
|
|
300
|
+
([CLI.md](CLI.md#backup-secret)); login neither creates nor exports it.
|
|
301
|
+
|
|
298
302
|
```sh
|
|
299
303
|
annon login --wallet evm
|
|
300
304
|
annon login --wallet near --network near:testnet
|
|
@@ -308,21 +312,44 @@ in the wallet.
|
|
|
308
312
|
| Wallet | How | Signing supported |
|
|
309
313
|
| --- | --- | --- |
|
|
310
314
|
| EVM | Injected EIP-1193 wallet on Base | `personal_sign` for the SDK's authorization texts, `eth_signTypedData_v4` for the exact EIP-3009/x402 payload |
|
|
311
|
-
| NEAR | Meteor Wallet (extension or web popup; mainnet and testnet) or HOT Wallet (mainnet only) through Wallet Selector, picked on the page
|
|
315
|
+
| NEAR | Meteor Wallet (extension or web popup; mainnet and testnet) or HOT Wallet (mainnet only) through Wallet Selector, picked on the page. NEP-413 messages are signed directly, with the account chosen in the wallet and no sign-in. Transactions take two clicks: an account-only sign-in (no `contractId`, no method list), then the transaction | NEP-413 and `signAndSendTransaction`, including the required deposit `"1"` on `ft_transfer_call` |
|
|
312
316
|
|
|
313
317
|
Browser and remote EVM split-deployment transactions and browser and remote Solana signing are not
|
|
314
318
|
included; the local-key adapters remain available for those workflows.
|
|
315
319
|
|
|
316
320
|
**The local page.** The listener binds `127.0.0.1` on an OS-assigned port before opening the browser.
|
|
317
321
|
Match the short pairing code with the terminal, and review the action, amount, recipients, file and
|
|
318
|
-
chain on the page before approving in the wallet.
|
|
322
|
+
chain on the page before approving in the wallet. The page shows a summary built only from the
|
|
323
|
+
request the wallet signs (amounts in USDC or NEAR, receiver, account, expiry), the CLI's payment or
|
|
324
|
+
listing terms apart from it with a warning if their price differs, and the raw request under
|
|
325
|
+
Technical details. While a request waits, the terminal prints its expiry on stderr.
|
|
326
|
+
|
|
327
|
+
- Each click opens at most one wallet window, inside that click, so the browser's pop-up blocker
|
|
328
|
+
allows it. If the wallet window closes, is blocked or declines before anything is sent, the page
|
|
329
|
+
says so and you can try again, with the same or another wallet, until the request expires.
|
|
330
|
+
Nothing is retried for you.
|
|
331
|
+
- Once the page has called the wallet's send for a transaction, that request is never attempted
|
|
332
|
+
again, whatever the wallet answers, because it may already have broadcast. The request ends as
|
|
333
|
+
`transaction_uncertain` and the terminal says: "The wallet may have sent the transaction. Do not
|
|
334
|
+
pay again. Run annon status <purchase id> to check it." The page records the send start with
|
|
335
|
+
the CLI before it calls the wallet, so a reloaded page or the request's expiry cannot turn it
|
|
336
|
+
into a retryable failure, and a result the CLI cannot verify after that point also ends as
|
|
337
|
+
uncertain. `annon buy` exits 4, `annon status` reports `submission: "uncertain"`, and the saved
|
|
338
|
+
purchase blocks a plain `annon buy` of the same file (`purchase_open`). `--force` overrides it
|
|
339
|
+
only after you have reconciled the first attempt (see CLI.md).
|
|
340
|
+
- The page reports only a fixed reason name (`window_closed`, `popup_blocked`, `rejected`,
|
|
341
|
+
`wallet_error`, `refused`, `send_uncertain`, `send_started` or `cancelled`) to the CLI, which
|
|
342
|
+
prints its own line for it. Cancel ends the request at once; an expired request fails with the
|
|
343
|
+
last reported reason, for example `rejected` or `wallet_error`, instead of a generic error. A
|
|
344
|
+
report never completes a request.
|
|
319
345
|
|
|
320
346
|
- Host (including port), Origin and an unpredictable RAM-only capability are checked on action and
|
|
321
347
|
result API calls.
|
|
322
348
|
- In open mode, a same-origin POST bootstraps the capability once into the opened page, then the
|
|
323
349
|
bootstrap route closes. With `--no-open`, bootstrap is disabled and the capability exists only in
|
|
324
350
|
the printed URL fragment. It is never passed to the browser launcher in argv.
|
|
325
|
-
- Bundled scripts
|
|
351
|
+
- Bundled scripts and a stylesheet from the page's own origin (no inline styles, fonts or other
|
|
352
|
+
resources), a restrictive CSP, no framing, `no-store` and `no-referrer` are enforced. The page
|
|
326
353
|
connects only to itself, the Wallet Selector's NEAR RPC (`free.rpc.fastnear.com` on mainnet,
|
|
327
354
|
`test.rpc.fastnear.com` on testnet, fixed in the page and independent of your configured RPC) and
|
|
328
355
|
HOT's relay `h4n.app`, and frames only `hot-labs.org`.
|
|
@@ -405,8 +432,11 @@ Order matters, because agent mode refuses `init`, `login` and per-call trust or
|
|
|
405
432
|
2. Write the deployment, `maxPrice`, `workDir` and, after reviewing the contract,
|
|
406
433
|
`trustContract: true` (or trust it once with a human command and `--trust-contract`). Do not set
|
|
407
434
|
`agent: true` yourself.
|
|
408
|
-
3. Run
|
|
409
|
-
|
|
435
|
+
3. Run bare `annon init` to create the backup secret, or give the launcher an absolute
|
|
436
|
+
`ANNON_BACKUP_SECRET_FILE` you manage ([CLI.md](CLI.md#backup-secret)). Agent mode never creates
|
|
437
|
+
one.
|
|
438
|
+
4. Run one `annon init --agent ...` from the examples above. It saves the signer, the daily budget
|
|
439
|
+
and `agent: true`. It does not create or reference a backup secret.
|
|
410
440
|
|
|
411
441
|
- Agents never prompt. Missing trust, price cap or daily budget causes a refusal.
|
|
412
442
|
- `allowedResources` is optional. Without it, any secure resource URL is allowed within the
|
|
@@ -447,7 +477,8 @@ Before a human payment the CLI confirms the current price, split recipients and
|
|
|
447
477
|
and file, token and network. Browser mode shows these exact terms with each signing request for
|
|
448
478
|
approval in the page and the wallet. Local and remote human signing require an explicit terminal
|
|
449
479
|
confirmation. Purchase and recovery secrets still need the independent backup secret described in
|
|
450
|
-
CLI.md
|
|
480
|
+
[CLI.md](CLI.md#backup-secret) and created by `annon init`; login does not derive one from a
|
|
481
|
+
signature.
|
|
451
482
|
|
|
452
483
|
## Remote signer, HTTP JSON v1
|
|
453
484
|
|
|
@@ -501,9 +532,10 @@ RPC. A returned transaction hash alone never proves success.
|
|
|
501
532
|
- Definite mismatches and failed finalized transactions are rejected without saving the hash as
|
|
502
533
|
`nearSubmission` evidence. Only RPC unavailability or a non-final status keeps the outcome
|
|
503
534
|
uncertain.
|
|
504
|
-
- If submission or finalized verification is ambiguous, the CLI returns `state: "uncertain"
|
|
505
|
-
`purchaseId
|
|
506
|
-
|
|
535
|
+
- If submission or finalized verification is ambiguous, the CLI returns `state: "uncertain"` and
|
|
536
|
+
`purchaseId`, and keeps `nearSubmission: {state:"uncertain"}` in the encrypted purchase backup.
|
|
537
|
+
Both carry `txHash` only when the wallet returned a valid one. `annon buy` exits 4. Check status
|
|
538
|
+
for that saved purchase before buying again.
|
|
507
539
|
- Signing errors with a known hash also expose safe hash and purchase evidence, with exit code 4.
|
|
508
540
|
|
|
509
541
|
**Reference handler.** `node/signer-mock` exports `signerMock`, an authenticated HTTP
|
|
@@ -100,9 +100,10 @@ export interface Bought {
|
|
|
100
100
|
route: BuyRoute;
|
|
101
101
|
record: PurchaseRecord;
|
|
102
102
|
instructions?: Deposit;
|
|
103
|
+
/** `txHash` is absent when the wallet may have sent the transaction without returning one. */
|
|
103
104
|
uncertain?: {
|
|
104
105
|
purchaseId: string;
|
|
105
|
-
txHash
|
|
106
|
+
txHash?: string;
|
|
106
107
|
};
|
|
107
108
|
payment?: string;
|
|
108
109
|
}
|
package/dist/api/annon.js
CHANGED
|
@@ -869,11 +869,18 @@ export class Annon {
|
|
|
869
869
|
const next = {
|
|
870
870
|
...record,
|
|
871
871
|
revision: record.revision + 1,
|
|
872
|
-
nearSubmission: {
|
|
872
|
+
nearSubmission: {
|
|
873
|
+
state: 'uncertain',
|
|
874
|
+
...(error.txHash ? { txHash: error.txHash } : {}),
|
|
875
|
+
},
|
|
873
876
|
};
|
|
874
877
|
if (!(await store.compareAndSet(purchaseKey(id), record, next)))
|
|
875
878
|
throw new TransactionUncertain(error.txHash, id);
|
|
876
|
-
return {
|
|
879
|
+
return {
|
|
880
|
+
route,
|
|
881
|
+
record: next,
|
|
882
|
+
uncertain: { purchaseId: id, ...(error.txHash ? { txHash: error.txHash } : {}) },
|
|
883
|
+
};
|
|
877
884
|
}
|
|
878
885
|
return { route, record };
|
|
879
886
|
}
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -18,6 +18,6 @@ export { type CatalogEntry, type CatalogQuery, type ConfiguredShop, canonicalMan
|
|
|
18
18
|
export { TransactionUncertain } from '../wallet/uncertain.js';
|
|
19
19
|
export { type EvmWallet, FileFundingRefused, type IdentityWallet, type NearWallet, } from '../wallet/wallet.js';
|
|
20
20
|
export { BROWSER_DOWNLOAD_LIMIT, type BrowserDownloadOptions, type BrowserDownloadProgress, browserDownload, } from './download.js';
|
|
21
|
-
export { type BrowserOpenOptions, BrowserPurchaseController, type BrowserPurchaseRecord, type BrowserPurchaseState, type BrowserPurchaseStorage, browserAnnon, browserPurchaseStorage, type ControllerOptions, PurchaseLeaseBusy, type PurchaseProgress, type PurchaseSdk, type PurchaseTermsReview, } from './purchases.js';
|
|
21
|
+
export { type BrowserOpenOptions, BrowserPurchaseController, type BrowserPurchaseRecord, type BrowserPurchaseState, type BrowserPurchaseStorage, browserAnnon, browserPurchaseStorage, type ControllerOptions, PurchaseLeaseBusy, type PurchaseProgress, type PurchaseSdk, type PurchaseTermsReview, type ReconcileOptions, type ReconcileResult, } from './purchases.js';
|
|
22
22
|
export { type BrowserSaleIndex, type BrowserSellerOptions, browserSellerSpool, browserSellerStorage, createBrowserSeller, type SaleHandle, type SaleView, type SellDraft, type SellerConnection, type SellerFacade, type SellProgress, type SellQuote, type SellStep, type SellTerms, } from './selling.js';
|
|
23
23
|
export { type BrowserNearProvider, type BrowserNearTransaction, BrowserWalletError, type BrowserWalletErrorCode, browserEvmWallet, browserNearWallet, browserSolanaWallet, type InjectedEvmProvider, type InjectedSolanaKey, type InjectedSolanaProvider, signNearUpload, } from './wallets.js';
|