@smartledger/bsv 9.8.0 → 9.10.0

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/bsv.d.ts CHANGED
@@ -1392,6 +1392,351 @@ declare module '@smartledger/bsv' {
1392
1392
  }
1393
1393
  }
1394
1394
 
1395
+ // -------- NotaryHash (BRC-220) --------------------------------------
1396
+
1397
+ /**
1398
+ * BRC-220 NotaryHash: build, anchor and verify detached-signature proofs.
1399
+ *
1400
+ * Certificates are in the BRC-220 reference implementation's JSON format.
1401
+ * Certificates written by 8.3.0–9.8.0 (`version: 1`, numeric `mode`) are still
1402
+ * read — `verify()` reports them as `legacy` — and never written.
1403
+ */
1404
+ export namespace NotaryHash {
1405
+ /**
1406
+ * The ON-CHAIN record's mode byte. A certificate's `mode` is 'full' | 'hybrid';
1407
+ * a batch is marked by `anchor.type`, not by the mode.
1408
+ */
1409
+ const MODE: { readonly FULL: 0; readonly HYBRID: 1; readonly BATCH: 2 };
1410
+
1411
+ type CertificateMode = 'full' | 'hybrid';
1412
+ /** How `publicKey` and `signature` are written. Not the signature's byte format. */
1413
+ type CertificateEncoding = 'hex' | 'base64';
1414
+ type AnchorType = 'direct' | 'batch';
1415
+ type Side = 'left' | 'right';
1416
+
1417
+ /** One audit-path sibling, leaf upward; `side` is its place relative to the running hash. */
1418
+ interface AuditPathNode<H = string> { hash: H; side: Side; }
1419
+
1420
+ interface Anchor {
1421
+ type: AnchorType;
1422
+ network: string;
1423
+ txid: string;
1424
+ vout: number;
1425
+ blockHeight: number | null;
1426
+ blockTime: number | null;
1427
+ }
1428
+
1429
+ interface MerkleProof {
1430
+ root: string;
1431
+ leafIndex: number;
1432
+ leafCount: number;
1433
+ path: AuditPathNode[];
1434
+ }
1435
+
1436
+ interface SPVEnvelope {
1437
+ rawTx: string;
1438
+ blockHash: string;
1439
+ blockHeight: number;
1440
+ merkleProof: { index: number; nodes: string[] };
1441
+ /** Defaults to 'TSC'. */
1442
+ format?: string;
1443
+ }
1444
+
1445
+ /** A BRC-220 certificate, as the reference implementation writes it. */
1446
+ interface Certificate {
1447
+ protocol: 'NotaryHash';
1448
+ version: '1.0';
1449
+ mode: CertificateMode;
1450
+ algorithm: string;
1451
+ hashAlgorithm: string;
1452
+ /** Always hex. */
1453
+ payloadHash: string;
1454
+ /** The FULL key, in every mode, written per `encoding`. */
1455
+ publicKey: string;
1456
+ /** The FULL signature, in every mode, written per `encoding`. */
1457
+ signature: string;
1458
+ encoding: CertificateEncoding;
1459
+ /** Always hex. SHA-256 of the canonical proof bytes, not of this JSON. */
1460
+ proofHash: string;
1461
+ /** ISO 8601, whole seconds — the value inside proofHash. */
1462
+ createdAt: string;
1463
+ anchor: Anchor;
1464
+ /** Present when `anchor.type` is 'batch'. */
1465
+ merkle?: MerkleProof;
1466
+ spv?: SPVEnvelope;
1467
+ }
1468
+
1469
+ /** The raw proof fields a certificate's strings decode to. */
1470
+ interface ProofFields {
1471
+ algorithm: string;
1472
+ hashAlgorithm: string;
1473
+ payloadHash: Buffer;
1474
+ publicKey: Buffer;
1475
+ signature: Buffer;
1476
+ createdAtUnix: number;
1477
+ }
1478
+
1479
+ interface BuildParams {
1480
+ mode: CertificateMode;
1481
+ algorithm: string;
1482
+ /** 'SHA-256' for every algorithm BRC-220 lists. */
1483
+ hashAlgorithm: string;
1484
+ payloadHash: Buffer;
1485
+ /** Raw bytes, FULL even in hybrid mode. */
1486
+ publicKey: Buffer;
1487
+ /** Raw bytes as the signer produced them. */
1488
+ signature: Buffer;
1489
+ /** Defaults to 'hex'. */
1490
+ encoding?: CertificateEncoding;
1491
+ /** Defaults to now. */
1492
+ createdAt?: string | Date;
1493
+ /** Whole seconds; an alternative to `createdAt`. */
1494
+ createdAtUnix?: number;
1495
+ anchor: {
1496
+ txid: string;
1497
+ /** Inferred from whether `merkle` is given. */
1498
+ type?: AnchorType;
1499
+ network?: string;
1500
+ vout?: number;
1501
+ blockHeight?: number | null;
1502
+ blockTime?: number | null;
1503
+ };
1504
+ /** Makes the certificate batch-anchored. Bare Merkle.path() hashes are converted. */
1505
+ merkle?: {
1506
+ root: Buffer | string;
1507
+ leafIndex: number;
1508
+ leafCount: number;
1509
+ path: Array<AuditPathNode<Buffer | string> | Buffer | string>;
1510
+ };
1511
+ }
1512
+
1513
+ /**
1514
+ * A certificate in the 8.3.0–9.8.0 format — what `build()` writes when `format` is
1515
+ * omitted, through 9.x. No other BRC-220 implementation reads it.
1516
+ */
1517
+ interface LegacyCertificate {
1518
+ protocol: 'NotaryHash';
1519
+ version: 1;
1520
+ /** The on-chain mode byte. */
1521
+ mode: 0 | 1 | 2;
1522
+ algorithm: string;
1523
+ hashAlgorithm: string;
1524
+ payloadHash: string;
1525
+ publicKey: string;
1526
+ signature: string;
1527
+ /** Hex either way; named for the signature's byte form. */
1528
+ encoding: 'raw' | 'der';
1529
+ proofHash: string;
1530
+ createdAt: string;
1531
+ anchor: { txid: string; blockHeight?: number };
1532
+ /** Mode 2 only; the path is bare hex hashes. */
1533
+ merkle?: { root: string; leafIndex: number; leafCount: number; path: string[] };
1534
+ spv?: SPVEnvelope;
1535
+ }
1536
+
1537
+ interface LegacyBuildParams {
1538
+ /** Omitted: the 9.x default, which warns once. 'legacy' pins it without the notice. */
1539
+ format?: 'legacy';
1540
+ mode: 0 | 1 | 2;
1541
+ algorithm: string;
1542
+ hashAlgorithm: string;
1543
+ payloadHash: Buffer;
1544
+ publicKey: Buffer;
1545
+ signature: Buffer;
1546
+ /** Defaults to 'raw'. */
1547
+ encoding?: 'raw' | 'der';
1548
+ /** Defaults to now. Written as supplied. */
1549
+ createdAt?: string | Date;
1550
+ anchor: { txid: string; blockHeight?: number };
1551
+ /** Required for mode 2. */
1552
+ merkle?: { root: string; leafIndex: number; leafCount: number; path: string[] };
1553
+ }
1554
+
1555
+ namespace Certificate {
1556
+ const PROTOCOL: 'NotaryHash';
1557
+ /** What the 9.x default format writes. Becomes '1.0' in 10.0.0, with the default. */
1558
+ const VERSION: 1;
1559
+ /** What the reference format writes. */
1560
+ const REFERENCE_VERSION: '1.0';
1561
+ const FORMAT: { readonly REFERENCE: 'reference'; readonly LEGACY: 'legacy' };
1562
+ const MODE: { readonly FULL: 'full'; readonly HYBRID: 'hybrid' };
1563
+ /** HEX and BASE64 are the reference format's; RAW and DER the legacy format's. */
1564
+ const ENCODING: { readonly HEX: 'hex'; readonly BASE64: 'base64'; readonly RAW: 'raw'; readonly DER: 'der' };
1565
+ const ANCHOR_TYPE: { readonly DIRECT: 'direct'; readonly BATCH: 'batch' };
1566
+ /** 'bsv-mainnet'. */
1567
+ const DEFAULT_NETWORK: string;
1568
+ const REQUIRED_FIELDS: string[];
1569
+ /**
1570
+ * Build a certificate in the BRC-220 reference format. proofHash is computed
1571
+ * here, never accepted.
1572
+ */
1573
+ function build(params: BuildParams & { format: 'reference' }): Certificate;
1574
+ /**
1575
+ * Build a certificate in the 8.3.0–9.8.0 format. Omitting `format` selects this
1576
+ * and warns once; the default becomes 'reference' in 10.0.0.
1577
+ */
1578
+ function build(params: LegacyBuildParams): LegacyCertificate;
1579
+ /** True for a certificate in the 8.3.0–9.8.0 format. */
1580
+ function isLegacy(certificate: object | null | undefined): boolean;
1581
+ /**
1582
+ * Map an 8.3.0–9.8.0 certificate onto the reference format. Anything else is
1583
+ * returned as given, for validateShape to judge.
1584
+ */
1585
+ function normalize(certificate: object): Certificate;
1586
+ /** Decode a string field. Hex may carry `0x`; base64 may be URL-safe or unpadded. */
1587
+ function decodeBytes(value: string, encoding: CertificateEncoding, name?: string): Buffer;
1588
+ function toProofInput(certificate: object): ProofFields;
1589
+ function recomputeProofHash(certificate: object): Buffer;
1590
+ /** Validity check 2. Strict boolean; false on anything malformed. */
1591
+ function proofHashMatches(certificate: object | null | undefined): boolean;
1592
+ /** Shape only — NOT verification. Empty means well-formed. */
1593
+ function validateShape(certificate: object | null | undefined): string[];
1594
+ /** A new certificate with the envelope attached; proofHash never changes. */
1595
+ function attachSPV<C extends Certificate | LegacyCertificate>(certificate: C, spv: SPVEnvelope): C & { spv: SPVEnvelope };
1596
+ /** RFC 8785 JSON of the certificate. Not what proofHash is computed over. */
1597
+ function canonicalize(certificate: object): string;
1598
+ }
1599
+
1600
+ namespace Encoding {
1601
+ /** 'NotaryHash/1.0', the domain prefix inside the canonical bytes. */
1602
+ const PROTOCOL_PREFIX: string;
1603
+ const VERSION: number;
1604
+ /** `u32be(len(x)) || x`. A string is encoded as UTF-8. */
1605
+ function lp(value: Buffer | string): Buffer;
1606
+ function u64be(seconds: number): Buffer;
1607
+ function toUnixSeconds(createdAt: string | Date): number;
1608
+ function canonicalBytes(fields: ProofFields): Buffer;
1609
+ /** SHA-256 of canonicalBytes. */
1610
+ function proofHash(fields: ProofFields): Buffer;
1611
+ }
1612
+
1613
+ interface DirectRecord {
1614
+ mode: 0 | 1;
1615
+ version: number;
1616
+ algorithm: string;
1617
+ hashAlgorithm: string;
1618
+ payloadHash: Buffer;
1619
+ proofHash: Buffer;
1620
+ /** Full mode. */
1621
+ publicKey?: Buffer;
1622
+ signature?: Buffer;
1623
+ /** Hybrid mode: SHA-256 of each. */
1624
+ publicKeyHash?: Buffer;
1625
+ signatureHash?: Buffer;
1626
+ }
1627
+ interface BatchRecord {
1628
+ mode: 2;
1629
+ version: number;
1630
+ merkleRoot: Buffer;
1631
+ leafCount: number;
1632
+ }
1633
+ type OnChainRecord = DirectRecord | BatchRecord;
1634
+
1635
+ interface RecordParams {
1636
+ mode: 'full' | 'hybrid' | 'batch' | 0 | 1 | 2;
1637
+ algorithm?: string;
1638
+ hashAlgorithm?: string;
1639
+ payloadHash?: Buffer;
1640
+ proofHash?: Buffer;
1641
+ /** FULL form in every mode; hybrid puts its digest on chain. */
1642
+ publicKey?: Buffer;
1643
+ signature?: Buffer;
1644
+ merkleRoot?: Buffer;
1645
+ leafCount?: number;
1646
+ }
1647
+
1648
+ /** The OP_FALSE OP_RETURN record. */
1649
+ namespace Script {
1650
+ const PREFIX: 'NOTARYHASH';
1651
+ const VERSION: number;
1652
+ const MODE: { readonly FULL: 0; readonly HYBRID: 1; readonly BATCH: 2 };
1653
+ function build(record: RecordParams): import('@smartledger/bsv').Script;
1654
+ /** Throws, naming the problem, rather than returning a partial record. */
1655
+ function parse(script: import('@smartledger/bsv').Script | string): OnChainRecord;
1656
+ /** A cheap filter: true means parse() is worth attempting, not that it will succeed. */
1657
+ function isNotaryHash(script: import('@smartledger/bsv').Script | string): boolean;
1658
+ }
1659
+
1660
+ /** RFC 6962 — NOT the Bitcoin Merkle tree. Leaf datum is proofHash. */
1661
+ namespace Merkle {
1662
+ const LEAF_PREFIX: number;
1663
+ const NODE_PREFIX: number;
1664
+ function hashLeaf(d: Buffer): Buffer;
1665
+ function hashNode(left: Buffer, right: Buffer): Buffer;
1666
+ function largestPowerOfTwoBelow(n: number): number;
1667
+ function root(leaves: Buffer[]): Buffer;
1668
+ /** Bare sibling hashes, leaf upward. Folding them needs index and leafCount. */
1669
+ function path(leaves: Buffer[], index: number): Buffer[];
1670
+ function foldPath(leafData: Buffer, index: number, leafCount: number, path: Buffer[]): Buffer;
1671
+ function verifyInclusion(leafData: Buffer, index: number, leafCount: number, path: Buffer[], expectedRoot: Buffer): boolean;
1672
+ function pathSides(index: number, leafCount: number): Side[];
1673
+ /** The path as certificates carry it: { hash, side }, leaf upward. */
1674
+ function auditPath(leaves: Buffer[], index: number): Array<AuditPathNode<Buffer>>;
1675
+ function rootFromPath(leafData: Buffer, path: Array<AuditPathNode<Buffer | string>>): Buffer;
1676
+ /** Strict boolean; false on anything malformed. */
1677
+ function verifyAuditPath(leafData: Buffer, path: Array<AuditPathNode<Buffer | string>>, expectedRoot: Buffer): boolean;
1678
+ }
1679
+
1680
+ /** A signature suite. `verify` must return a strict boolean; anything else counts as false. */
1681
+ interface Suite {
1682
+ verify(payloadHash: Buffer, signature: Buffer, publicKey: Buffer): boolean;
1683
+ }
1684
+
1685
+ namespace Suites {
1686
+ function register(algorithm: string, suite: Suite): typeof Suites;
1687
+ function get(algorithm: string): Suite | undefined;
1688
+ function list(): string[];
1689
+ function unregister(algorithm: string): typeof Suites;
1690
+ /** An unregistered algorithm is false, never a fallback to ECDSA. */
1691
+ function verify(algorithm: string, payloadHash: Buffer, signature: Buffer, publicKey: Buffer): boolean;
1692
+ }
1693
+
1694
+ interface AnchorOptions {
1695
+ /** An independently obtained block header: a bsv BlockHeader, 80 bytes, or 80-byte hex. */
1696
+ header?: string | Buffer | object;
1697
+ /**
1698
+ * The height the header was obtained at. Its 80 bytes do not carry it, so pass
1699
+ * it to have it checked against `spv.blockHeight`.
1700
+ */
1701
+ height?: number;
1702
+ /** Pass false only for test fixtures. Defaults to true. */
1703
+ requirePow?: boolean;
1704
+ }
1705
+ interface VerifyOptions extends AnchorOptions {
1706
+ /** Checks 1 and 2 only. The result is never `valid`. */
1707
+ skipAnchor?: boolean;
1708
+ }
1709
+ interface CheckResult { valid: boolean; errors: string[]; }
1710
+ interface VerifyReport {
1711
+ /** The verdict. The report itself is always truthy — read this. */
1712
+ valid: boolean;
1713
+ shape: string[];
1714
+ signature: boolean;
1715
+ proofIntegrity: boolean;
1716
+ anchor: boolean;
1717
+ /** Set once the anchor has been checked. */
1718
+ batchInclusion?: boolean;
1719
+ /** True for a certificate written by 8.3.0–9.8.0. */
1720
+ legacy: boolean;
1721
+ errors: string[];
1722
+ }
1723
+
1724
+ function registerSuite(algorithm: string, suite: Suite): typeof Suites;
1725
+ /** Check 1, offline. */
1726
+ function verifySignature(certificate: object): boolean;
1727
+ /** `reverse(SHA256(SHA256(rawTx)))`, as displayed. */
1728
+ function txidFromRawTx(rawTx: Buffer | string): string;
1729
+ function recordFromRawTx(rawTx: Buffer | string): OnChainRecord | null;
1730
+ function recordMatchesCertificate(record: OnChainRecord, certificate: object): boolean;
1731
+ /** Check 3. Without a header this is never valid. */
1732
+ function verifyAnchorSPV(certificate: object, opts?: AnchorOptions): CheckResult;
1733
+ function verifyBatchInclusion(certificate: object): CheckResult;
1734
+ /** All three checks, reported separately. */
1735
+ function verify(certificate: object, opts?: VerifyOptions): VerifyReport;
1736
+ /** Strict boolean verdict, for `if (...)`. */
1737
+ function isValid(certificate: object, opts?: VerifyOptions): boolean;
1738
+ }
1739
+
1395
1740
  // -------- Ordinals (1Sat Ordinals inscriptions + marketplace) -------
1396
1741
 
1397
1742
  export namespace Ordinals {