@defdone/annon 0.1.0-alpha.0 → 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 +15 -0
- package/CLI.md +116 -10
- package/README.md +57 -15
- 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 +113 -77
- 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 -101
- package/dist/browser/purchase-bundle.js +45 -45
- 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 -3
- 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 +9 -0
- package/dist/node/browser-login.js +75 -14
- 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/signer-wallet.js +3 -1
- 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/base.js +36 -43
- package/dist/pay/purchase.d.ts +2 -1
- package/dist/wallet/account-only.d.ts +1 -1
- package/dist/wallet/account-only.js +1 -1
- package/dist/wallet/uncertain.d.ts +6 -3
- package/dist/wallet/uncertain.js +4 -1
- package/package.json +3 -2
package/dist/pay/base.js
CHANGED
|
@@ -298,32 +298,44 @@ async function lastBlock(url, from, validBefore, now) {
|
|
|
298
298
|
return at;
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
|
-
/**
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
301
|
+
/** Note: blocks per eth_getLogs, the common RPC limit (QuickNode refuses a wider range). */
|
|
302
|
+
const LOG_RANGE = 10_000;
|
|
303
|
+
/**
|
|
304
|
+
* USDC's logs for `topics` (a list in a position matches any of it) in `[from, to]`, read in
|
|
305
|
+
* chunks of `LOG_RANGE` blocks, earliest first. Each chunk's logs must answer that chunk's query.
|
|
306
|
+
* Stops after the first chunk with a log `enough` accepts; an empty range reads nothing.
|
|
307
|
+
*/
|
|
308
|
+
async function usdcLogs(url, usdc, topics, from, to, enough) {
|
|
309
|
+
const all = [];
|
|
310
|
+
for (let at = from; at <= to; at += LOG_RANGE) {
|
|
311
|
+
const end = Math.min(to, at + LOG_RANGE - 1);
|
|
311
312
|
const found = await ask(url, 'eth_getLogs', [
|
|
312
|
-
{ address:
|
|
313
|
+
{ address: usdc, fromBlock: qty(at), toBlock: qty(end), topics },
|
|
313
314
|
]);
|
|
314
315
|
if (!Array.isArray(found))
|
|
315
316
|
return malformed('eth_getLogs result');
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
317
|
+
const logs = found.map(evmLog).filter((l) => !l.removed);
|
|
318
|
+
// Every log must answer the query; anything else is an RPC that can't be believed.
|
|
319
|
+
for (const l of logs) {
|
|
320
|
+
if (l.address !== strip(usdc) ||
|
|
321
|
+
l.topics.length !== topics.length ||
|
|
322
|
+
!topics.every((t, i) => [t].flat().some((x) => strip(x) === l.topics[i])) ||
|
|
319
323
|
l.block_number < at ||
|
|
320
324
|
l.block_number > end) {
|
|
321
325
|
return malformed('eth_getLogs returned a log the query did not ask for');
|
|
322
326
|
}
|
|
323
|
-
return l.block_number;
|
|
324
327
|
}
|
|
328
|
+
all.push(...logs);
|
|
329
|
+
if (logs.some(enough))
|
|
330
|
+
break;
|
|
325
331
|
}
|
|
326
|
-
return
|
|
332
|
+
return all;
|
|
333
|
+
}
|
|
334
|
+
/** The block of an `AuthorizationCanceled` for this nonce in `[from, to]`. */
|
|
335
|
+
async function canceledAfter(url, e, from, to) {
|
|
336
|
+
const topics = [TOPICS.authorizationCanceled, toHex(addressWord(e.from)), e.nonce.toLowerCase()];
|
|
337
|
+
const [first] = await usdcLogs(url, e.usdc, topics, from, to, () => true);
|
|
338
|
+
return first ? first.block_number : null;
|
|
327
339
|
}
|
|
328
340
|
/**
|
|
329
341
|
* Where a signed purchase stands, found by its nonce alone, so a lost transaction hash loses
|
|
@@ -338,33 +350,14 @@ export async function paymentStatus(url, e) {
|
|
|
338
350
|
const final = await block(url, 'finalized');
|
|
339
351
|
const now = await head(url);
|
|
340
352
|
const last = await lastBlock(url, e.block, e.validBefore, now);
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
],
|
|
350
|
-
};
|
|
351
|
-
const found = await ask(url, 'eth_getLogs', [query]);
|
|
352
|
-
if (!Array.isArray(found))
|
|
353
|
-
return malformed('eth_getLogs result');
|
|
354
|
-
const logs = found.map(evmLog).filter((l) => !l.removed);
|
|
355
|
-
// Every log must answer the query; anything else is an RPC that can't be believed.
|
|
356
|
-
for (const l of logs) {
|
|
357
|
-
if (l.address !== strip(e.usdc) ||
|
|
358
|
-
l.topics.length !== 3 ||
|
|
359
|
-
!query.topics[0].some((t) => strip(t) === l.topics[0]) ||
|
|
360
|
-
l.topics[1] !== topicOf(e.from) ||
|
|
361
|
-
l.topics[2] !== strip(e.nonce) ||
|
|
362
|
-
l.block_number < e.block ||
|
|
363
|
-
l.block_number > last) {
|
|
364
|
-
return malformed('eth_getLogs returned a log the query did not ask for');
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
const used = logs.find((l) => l.topics[0] === strip(TOPICS.authorizationUsed));
|
|
353
|
+
// A used authorization in any chunk wins over a cancellation, so only that ends the search.
|
|
354
|
+
const usedTopic = strip(TOPICS.authorizationUsed);
|
|
355
|
+
const logs = await usdcLogs(url, e.usdc, [
|
|
356
|
+
[TOPICS.authorizationUsed, TOPICS.authorizationCanceled],
|
|
357
|
+
toHex(addressWord(e.from)),
|
|
358
|
+
e.nonce.toLowerCase(),
|
|
359
|
+
], e.block, last, (l) => l.topics[0] === usedTopic);
|
|
360
|
+
const used = logs.find((l) => l.topics[0] === usedTopic);
|
|
368
361
|
if (used) {
|
|
369
362
|
const receipt = await ask(url, 'eth_getTransactionReceipt', [`0x${used.transaction_hash}`]);
|
|
370
363
|
const paid = paymentLogs(receipt, e);
|
package/dist/pay/purchase.d.ts
CHANGED
|
@@ -76,9 +76,10 @@ export interface PurchaseRecord extends Versioned {
|
|
|
76
76
|
recoveryProved: boolean;
|
|
77
77
|
/** Source details are the reviewed 1Click quote. */
|
|
78
78
|
payment: PaymentSummary;
|
|
79
|
+
/** A NEAR send that may be on chain; `txHash` only when the wallet returned one. */
|
|
79
80
|
nearSubmission?: {
|
|
80
81
|
state: 'uncertain';
|
|
81
|
-
txHash
|
|
82
|
+
txHash?: string;
|
|
82
83
|
};
|
|
83
84
|
paymentState?: 'expired' | 'canceled';
|
|
84
85
|
purchase: Purchase;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Never supply contractId/methodNames:
|
|
1
|
+
/** Never supply contractId/methodNames: a wallet would otherwise add a function-call key for them. */
|
|
2
2
|
export declare function signInAccountOnly(wallet: {
|
|
3
3
|
signOut?: () => Promise<void>;
|
|
4
4
|
signIn(params: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Never supply contractId/methodNames:
|
|
1
|
+
/** Never supply contractId/methodNames: a wallet would otherwise add a function-call key for them. */
|
|
2
2
|
export async function signInAccountOnly(wallet) {
|
|
3
3
|
// A reused loopback origin may contain older connector authority. Never let it sign silently.
|
|
4
4
|
await wallet.signOut?.();
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { AnnonError } from '../errors.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Public evidence to retain whenever a submitted NEAR transaction cannot be confirmed. `txHash` is
|
|
4
|
+
* absent when a wallet may have broadcast but never returned a hash: unknown, never invented.
|
|
5
|
+
*/
|
|
3
6
|
export declare class TransactionUncertain extends AnnonError {
|
|
4
|
-
readonly txHash: string;
|
|
7
|
+
readonly txHash: string | undefined;
|
|
5
8
|
readonly purchaseId?: string | undefined;
|
|
6
9
|
readonly code = "transaction_uncertain";
|
|
7
|
-
constructor(txHash: string, purchaseId?: string | undefined);
|
|
10
|
+
constructor(txHash: string | undefined, purchaseId?: string | undefined);
|
|
8
11
|
}
|
package/dist/wallet/uncertain.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { AnnonError } from '../errors.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Public evidence to retain whenever a submitted NEAR transaction cannot be confirmed. `txHash` is
|
|
4
|
+
* absent when a wallet may have broadcast but never returned a hash: unknown, never invented.
|
|
5
|
+
*/
|
|
3
6
|
export class TransactionUncertain extends AnnonError {
|
|
4
7
|
txHash;
|
|
5
8
|
purchaseId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defdone/annon",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.2",
|
|
4
4
|
"description": "Files only the buyer can open: encrypted on the client, the key released by NEAR once the payment is verified.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://annon.dev",
|
|
@@ -115,7 +115,8 @@
|
|
|
115
115
|
],
|
|
116
116
|
"devDependencies": {
|
|
117
117
|
"@near-wallet-selector/core": "10.1.4",
|
|
118
|
-
"@near-wallet-selector/
|
|
118
|
+
"@near-wallet-selector/hot-wallet": "10.1.4",
|
|
119
|
+
"@near-wallet-selector/meteor-wallet": "10.1.4",
|
|
119
120
|
"@types/node": "26.6.5",
|
|
120
121
|
"buffer": "6.0.3",
|
|
121
122
|
"esbuild": "0.28.2",
|