@entros/pulse-sdk 1.4.2 → 1.5.1

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/dist/index.mjs CHANGED
@@ -508,6 +508,26 @@ function extractFormantRatios(samples, sampleRate, frameSize, hopSize) {
508
508
  return { f1f2, f2f3 };
509
509
  }
510
510
 
511
+ // src/yield.ts
512
+ function yieldToMainThread() {
513
+ return new Promise((resolve) => {
514
+ if (typeof MessageChannel !== "undefined") {
515
+ const channel = new MessageChannel();
516
+ channel.port1.onmessage = () => {
517
+ channel.port1.close();
518
+ resolve();
519
+ };
520
+ channel.port2.postMessage(null);
521
+ return;
522
+ }
523
+ if (typeof setTimeout !== "undefined") {
524
+ setTimeout(resolve, 0);
525
+ return;
526
+ }
527
+ resolve();
528
+ });
529
+ }
530
+
511
531
  // src/extraction/speaker.ts
512
532
  function getFrameSize(sampleRate) {
513
533
  const MIN_F0 = 50;
@@ -740,6 +760,7 @@ async function extractSpeakerFeaturesDetailed(audio) {
740
760
  normalizedSamples = samples;
741
761
  }
742
762
  const { f0, amplitudes: normalizedAmplitudes, periods } = await detectF0Contour(normalizedSamples, sampleRate);
763
+ await yieldToMainThread();
743
764
  const amplitudes = [];
744
765
  for (let i = 0; i < numFrames; i++) {
745
766
  const start = i * hopSize;
@@ -764,6 +785,7 @@ async function extractSpeakerFeaturesDetailed(audio) {
764
785
  const hnrStats = condense(hnrValues);
765
786
  const hnrEntropy = entropy(hnrValues);
766
787
  const hnrFeatures = [hnrStats.mean, hnrStats.variance, hnrStats.skewness, hnrStats.kurtosis, hnrEntropy];
788
+ await yieldToMainThread();
767
789
  const { f1f2, f2f3 } = extractFormantRatios(normalizedSamples, sampleRate, frameSize, hopSize);
768
790
  const f1f2Stats = condense(f1f2);
769
791
  const f2f3Stats = condense(f2f3);
@@ -777,6 +799,7 @@ async function extractSpeakerFeaturesDetailed(audio) {
777
799
  f2f3Stats.skewness,
778
800
  f2f3Stats.kurtosis
779
801
  ];
802
+ await yieldToMainThread();
780
803
  const ltasFeatures = await computeLTAS(samples, sampleRate);
781
804
  const voicingFeatures = [voicedRatio];
782
805
  const ampStats = condense(amplitudes);
@@ -1273,6 +1296,2255 @@ async function generateSolanaProof(current, previous, wasmPath, zkeyPath, thresh
1273
1296
  return serializeProof(proof, publicSignals);
1274
1297
  }
1275
1298
 
1299
+ // src/protocol/idl/entros_anchor.json
1300
+ var entros_anchor_default = {
1301
+ address: "GZYwTp2ozeuRA5Gof9vs4ya961aANcJBdUzB7LN6q4b2",
1302
+ metadata: {
1303
+ name: "entros_anchor",
1304
+ version: "0.1.0",
1305
+ spec: "0.1.0",
1306
+ description: "Non-transferable identity token for Entros Protocol"
1307
+ },
1308
+ docs: [
1309
+ "Mint account space for Token-2022 with NonTransferable extension.",
1310
+ "Base mint = 82 bytes, account type = 1 byte, extension type (2) + length (2) = 4 bytes,",
1311
+ "NonTransferable data = 0 bytes. Plus multisig padding from Token-2022.",
1312
+ "We use a constant derived from the Token-2022 spec."
1313
+ ],
1314
+ instructions: [
1315
+ {
1316
+ name: "authorize_new_wallet",
1317
+ docs: [
1318
+ "Authorize a new wallet by 2 signers. This can be done many times before invoking migrate_identity()"
1319
+ ],
1320
+ discriminator: [
1321
+ 178,
1322
+ 186,
1323
+ 185,
1324
+ 108,
1325
+ 51,
1326
+ 219,
1327
+ 107,
1328
+ 197
1329
+ ],
1330
+ accounts: [
1331
+ {
1332
+ name: "signer",
1333
+ writable: true,
1334
+ signer: true
1335
+ },
1336
+ {
1337
+ name: "identity_state",
1338
+ writable: true,
1339
+ pda: {
1340
+ seeds: [
1341
+ {
1342
+ kind: "const",
1343
+ value: [
1344
+ 105,
1345
+ 100,
1346
+ 101,
1347
+ 110,
1348
+ 116,
1349
+ 105,
1350
+ 116,
1351
+ 121
1352
+ ]
1353
+ },
1354
+ {
1355
+ kind: "account",
1356
+ path: "signer"
1357
+ }
1358
+ ]
1359
+ }
1360
+ },
1361
+ {
1362
+ name: "signer_new",
1363
+ writable: true,
1364
+ signer: true
1365
+ },
1366
+ {
1367
+ name: "token_program"
1368
+ },
1369
+ {
1370
+ name: "mint",
1371
+ writable: true,
1372
+ pda: {
1373
+ seeds: [
1374
+ {
1375
+ kind: "const",
1376
+ value: [
1377
+ 109,
1378
+ 105,
1379
+ 110,
1380
+ 116
1381
+ ]
1382
+ },
1383
+ {
1384
+ kind: "account",
1385
+ path: "signer"
1386
+ }
1387
+ ]
1388
+ }
1389
+ },
1390
+ {
1391
+ name: "token_account",
1392
+ writable: true,
1393
+ pda: {
1394
+ seeds: [
1395
+ {
1396
+ kind: "account",
1397
+ path: "signer"
1398
+ },
1399
+ {
1400
+ kind: "account",
1401
+ path: "token_program"
1402
+ },
1403
+ {
1404
+ kind: "account",
1405
+ path: "mint"
1406
+ }
1407
+ ],
1408
+ program: {
1409
+ kind: "const",
1410
+ value: [
1411
+ 140,
1412
+ 151,
1413
+ 37,
1414
+ 143,
1415
+ 78,
1416
+ 36,
1417
+ 137,
1418
+ 241,
1419
+ 187,
1420
+ 61,
1421
+ 16,
1422
+ 41,
1423
+ 20,
1424
+ 142,
1425
+ 13,
1426
+ 131,
1427
+ 11,
1428
+ 90,
1429
+ 19,
1430
+ 153,
1431
+ 218,
1432
+ 255,
1433
+ 16,
1434
+ 132,
1435
+ 4,
1436
+ 142,
1437
+ 123,
1438
+ 216,
1439
+ 219,
1440
+ 233,
1441
+ 248,
1442
+ 89
1443
+ ]
1444
+ }
1445
+ }
1446
+ }
1447
+ ],
1448
+ args: []
1449
+ },
1450
+ {
1451
+ name: "migrate_identity",
1452
+ docs: [
1453
+ "Migrate from an user's old Anchor IdentityState PDA to a new one",
1454
+ "After this function call, the orphaned 0-balance ATA, pointing at a closed mint, locks ~0.002 SOL of rent. This ATA can be recovered by the old wallet calling closeAccount()"
1455
+ ],
1456
+ discriminator: [
1457
+ 161,
1458
+ 192,
1459
+ 70,
1460
+ 80,
1461
+ 47,
1462
+ 37,
1463
+ 26,
1464
+ 10
1465
+ ],
1466
+ accounts: [
1467
+ {
1468
+ name: "user",
1469
+ writable: true,
1470
+ signer: true
1471
+ },
1472
+ {
1473
+ name: "identity_state",
1474
+ writable: true,
1475
+ pda: {
1476
+ seeds: [
1477
+ {
1478
+ kind: "const",
1479
+ value: [
1480
+ 105,
1481
+ 100,
1482
+ 101,
1483
+ 110,
1484
+ 116,
1485
+ 105,
1486
+ 116,
1487
+ 121
1488
+ ]
1489
+ },
1490
+ {
1491
+ kind: "account",
1492
+ path: "user"
1493
+ }
1494
+ ]
1495
+ }
1496
+ },
1497
+ {
1498
+ name: "mint",
1499
+ docs: [
1500
+ "initialization ordering. PDA seeds ensure uniqueness per user."
1501
+ ],
1502
+ writable: true,
1503
+ pda: {
1504
+ seeds: [
1505
+ {
1506
+ kind: "const",
1507
+ value: [
1508
+ 109,
1509
+ 105,
1510
+ 110,
1511
+ 116
1512
+ ]
1513
+ },
1514
+ {
1515
+ kind: "account",
1516
+ path: "user"
1517
+ }
1518
+ ]
1519
+ }
1520
+ },
1521
+ {
1522
+ name: "mint_authority",
1523
+ pda: {
1524
+ seeds: [
1525
+ {
1526
+ kind: "const",
1527
+ value: [
1528
+ 109,
1529
+ 105,
1530
+ 110,
1531
+ 116,
1532
+ 95,
1533
+ 97,
1534
+ 117,
1535
+ 116,
1536
+ 104,
1537
+ 111,
1538
+ 114,
1539
+ 105,
1540
+ 116,
1541
+ 121
1542
+ ]
1543
+ }
1544
+ ]
1545
+ }
1546
+ },
1547
+ {
1548
+ name: "token_account",
1549
+ writable: true
1550
+ },
1551
+ {
1552
+ name: "associated_token_program",
1553
+ address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
1554
+ },
1555
+ {
1556
+ name: "token_program"
1557
+ },
1558
+ {
1559
+ name: "system_program",
1560
+ address: "11111111111111111111111111111111"
1561
+ },
1562
+ {
1563
+ name: "protocol_config",
1564
+ pda: {
1565
+ seeds: [
1566
+ {
1567
+ kind: "const",
1568
+ value: [
1569
+ 112,
1570
+ 114,
1571
+ 111,
1572
+ 116,
1573
+ 111,
1574
+ 99,
1575
+ 111,
1576
+ 108,
1577
+ 95,
1578
+ 99,
1579
+ 111,
1580
+ 110,
1581
+ 102,
1582
+ 105,
1583
+ 103
1584
+ ]
1585
+ }
1586
+ ],
1587
+ program: {
1588
+ kind: "const",
1589
+ value: [
1590
+ 81,
1591
+ 130,
1592
+ 250,
1593
+ 230,
1594
+ 30,
1595
+ 253,
1596
+ 246,
1597
+ 69,
1598
+ 82,
1599
+ 96,
1600
+ 7,
1601
+ 173,
1602
+ 78,
1603
+ 160,
1604
+ 131,
1605
+ 188,
1606
+ 70,
1607
+ 106,
1608
+ 173,
1609
+ 59,
1610
+ 102,
1611
+ 163,
1612
+ 198,
1613
+ 189,
1614
+ 82,
1615
+ 37,
1616
+ 225,
1617
+ 38,
1618
+ 52,
1619
+ 233,
1620
+ 157,
1621
+ 117
1622
+ ]
1623
+ }
1624
+ }
1625
+ },
1626
+ {
1627
+ name: "treasury",
1628
+ writable: true,
1629
+ pda: {
1630
+ seeds: [
1631
+ {
1632
+ kind: "const",
1633
+ value: [
1634
+ 112,
1635
+ 114,
1636
+ 111,
1637
+ 116,
1638
+ 111,
1639
+ 99,
1640
+ 111,
1641
+ 108,
1642
+ 95,
1643
+ 116,
1644
+ 114,
1645
+ 101,
1646
+ 97,
1647
+ 115,
1648
+ 117,
1649
+ 114,
1650
+ 121
1651
+ ]
1652
+ }
1653
+ ],
1654
+ program: {
1655
+ kind: "const",
1656
+ value: [
1657
+ 81,
1658
+ 130,
1659
+ 250,
1660
+ 230,
1661
+ 30,
1662
+ 253,
1663
+ 246,
1664
+ 69,
1665
+ 82,
1666
+ 96,
1667
+ 7,
1668
+ 173,
1669
+ 78,
1670
+ 160,
1671
+ 131,
1672
+ 188,
1673
+ 70,
1674
+ 106,
1675
+ 173,
1676
+ 59,
1677
+ 102,
1678
+ 163,
1679
+ 198,
1680
+ 189,
1681
+ 82,
1682
+ 37,
1683
+ 225,
1684
+ 38,
1685
+ 52,
1686
+ 233,
1687
+ 157,
1688
+ 117
1689
+ ]
1690
+ }
1691
+ }
1692
+ },
1693
+ {
1694
+ name: "wallet_old",
1695
+ writable: true
1696
+ },
1697
+ {
1698
+ name: "identity_state_old",
1699
+ writable: true,
1700
+ pda: {
1701
+ seeds: [
1702
+ {
1703
+ kind: "const",
1704
+ value: [
1705
+ 105,
1706
+ 100,
1707
+ 101,
1708
+ 110,
1709
+ 116,
1710
+ 105,
1711
+ 116,
1712
+ 121
1713
+ ]
1714
+ },
1715
+ {
1716
+ kind: "account",
1717
+ path: "wallet_old"
1718
+ }
1719
+ ]
1720
+ }
1721
+ },
1722
+ {
1723
+ name: "mint_old",
1724
+ writable: true,
1725
+ pda: {
1726
+ seeds: [
1727
+ {
1728
+ kind: "const",
1729
+ value: [
1730
+ 109,
1731
+ 105,
1732
+ 110,
1733
+ 116
1734
+ ]
1735
+ },
1736
+ {
1737
+ kind: "account",
1738
+ path: "wallet_old"
1739
+ }
1740
+ ]
1741
+ }
1742
+ },
1743
+ {
1744
+ name: "token_account_old",
1745
+ writable: true,
1746
+ pda: {
1747
+ seeds: [
1748
+ {
1749
+ kind: "account",
1750
+ path: "wallet_old"
1751
+ },
1752
+ {
1753
+ kind: "account",
1754
+ path: "token_program"
1755
+ },
1756
+ {
1757
+ kind: "account",
1758
+ path: "mint_old"
1759
+ }
1760
+ ],
1761
+ program: {
1762
+ kind: "const",
1763
+ value: [
1764
+ 140,
1765
+ 151,
1766
+ 37,
1767
+ 143,
1768
+ 78,
1769
+ 36,
1770
+ 137,
1771
+ 241,
1772
+ 187,
1773
+ 61,
1774
+ 16,
1775
+ 41,
1776
+ 20,
1777
+ 142,
1778
+ 13,
1779
+ 131,
1780
+ 11,
1781
+ 90,
1782
+ 19,
1783
+ 153,
1784
+ 218,
1785
+ 255,
1786
+ 16,
1787
+ 132,
1788
+ 4,
1789
+ 142,
1790
+ 123,
1791
+ 216,
1792
+ 219,
1793
+ 233,
1794
+ 248,
1795
+ 89
1796
+ ]
1797
+ }
1798
+ }
1799
+ }
1800
+ ],
1801
+ args: []
1802
+ },
1803
+ {
1804
+ name: "mint_anchor",
1805
+ docs: [
1806
+ "Mint a new Entros Anchor identity for the caller.",
1807
+ "Creates a NonTransferable Token-2022 mint, mints 1 token to the user's ATA,",
1808
+ "and initializes the IdentityState PDA."
1809
+ ],
1810
+ discriminator: [
1811
+ 68,
1812
+ 56,
1813
+ 113,
1814
+ 102,
1815
+ 236,
1816
+ 152,
1817
+ 146,
1818
+ 60
1819
+ ],
1820
+ accounts: [
1821
+ {
1822
+ name: "user",
1823
+ writable: true,
1824
+ signer: true
1825
+ },
1826
+ {
1827
+ name: "identity_state",
1828
+ writable: true,
1829
+ pda: {
1830
+ seeds: [
1831
+ {
1832
+ kind: "const",
1833
+ value: [
1834
+ 105,
1835
+ 100,
1836
+ 101,
1837
+ 110,
1838
+ 116,
1839
+ 105,
1840
+ 116,
1841
+ 121
1842
+ ]
1843
+ },
1844
+ {
1845
+ kind: "account",
1846
+ path: "user"
1847
+ }
1848
+ ]
1849
+ }
1850
+ },
1851
+ {
1852
+ name: "mint",
1853
+ docs: [
1854
+ "initialization ordering. PDA seeds ensure uniqueness per user."
1855
+ ],
1856
+ writable: true,
1857
+ pda: {
1858
+ seeds: [
1859
+ {
1860
+ kind: "const",
1861
+ value: [
1862
+ 109,
1863
+ 105,
1864
+ 110,
1865
+ 116
1866
+ ]
1867
+ },
1868
+ {
1869
+ kind: "account",
1870
+ path: "user"
1871
+ }
1872
+ ]
1873
+ }
1874
+ },
1875
+ {
1876
+ name: "mint_authority",
1877
+ pda: {
1878
+ seeds: [
1879
+ {
1880
+ kind: "const",
1881
+ value: [
1882
+ 109,
1883
+ 105,
1884
+ 110,
1885
+ 116,
1886
+ 95,
1887
+ 97,
1888
+ 117,
1889
+ 116,
1890
+ 104,
1891
+ 111,
1892
+ 114,
1893
+ 105,
1894
+ 116,
1895
+ 121
1896
+ ]
1897
+ }
1898
+ ]
1899
+ }
1900
+ },
1901
+ {
1902
+ name: "token_account",
1903
+ writable: true
1904
+ },
1905
+ {
1906
+ name: "associated_token_program",
1907
+ address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
1908
+ },
1909
+ {
1910
+ name: "token_program"
1911
+ },
1912
+ {
1913
+ name: "system_program",
1914
+ address: "11111111111111111111111111111111"
1915
+ },
1916
+ {
1917
+ name: "protocol_config",
1918
+ pda: {
1919
+ seeds: [
1920
+ {
1921
+ kind: "const",
1922
+ value: [
1923
+ 112,
1924
+ 114,
1925
+ 111,
1926
+ 116,
1927
+ 111,
1928
+ 99,
1929
+ 111,
1930
+ 108,
1931
+ 95,
1932
+ 99,
1933
+ 111,
1934
+ 110,
1935
+ 102,
1936
+ 105,
1937
+ 103
1938
+ ]
1939
+ }
1940
+ ],
1941
+ program: {
1942
+ kind: "const",
1943
+ value: [
1944
+ 81,
1945
+ 130,
1946
+ 250,
1947
+ 230,
1948
+ 30,
1949
+ 253,
1950
+ 246,
1951
+ 69,
1952
+ 82,
1953
+ 96,
1954
+ 7,
1955
+ 173,
1956
+ 78,
1957
+ 160,
1958
+ 131,
1959
+ 188,
1960
+ 70,
1961
+ 106,
1962
+ 173,
1963
+ 59,
1964
+ 102,
1965
+ 163,
1966
+ 198,
1967
+ 189,
1968
+ 82,
1969
+ 37,
1970
+ 225,
1971
+ 38,
1972
+ 52,
1973
+ 233,
1974
+ 157,
1975
+ 117
1976
+ ]
1977
+ }
1978
+ }
1979
+ },
1980
+ {
1981
+ name: "treasury",
1982
+ writable: true,
1983
+ pda: {
1984
+ seeds: [
1985
+ {
1986
+ kind: "const",
1987
+ value: [
1988
+ 112,
1989
+ 114,
1990
+ 111,
1991
+ 116,
1992
+ 111,
1993
+ 99,
1994
+ 111,
1995
+ 108,
1996
+ 95,
1997
+ 116,
1998
+ 114,
1999
+ 101,
2000
+ 97,
2001
+ 115,
2002
+ 117,
2003
+ 114,
2004
+ 121
2005
+ ]
2006
+ }
2007
+ ],
2008
+ program: {
2009
+ kind: "const",
2010
+ value: [
2011
+ 81,
2012
+ 130,
2013
+ 250,
2014
+ 230,
2015
+ 30,
2016
+ 253,
2017
+ 246,
2018
+ 69,
2019
+ 82,
2020
+ 96,
2021
+ 7,
2022
+ 173,
2023
+ 78,
2024
+ 160,
2025
+ 131,
2026
+ 188,
2027
+ 70,
2028
+ 106,
2029
+ 173,
2030
+ 59,
2031
+ 102,
2032
+ 163,
2033
+ 198,
2034
+ 189,
2035
+ 82,
2036
+ 37,
2037
+ 225,
2038
+ 38,
2039
+ 52,
2040
+ 233,
2041
+ 157,
2042
+ 117
2043
+ ]
2044
+ }
2045
+ }
2046
+ },
2047
+ {
2048
+ name: "instructions_sysvar",
2049
+ docs: [
2050
+ "receipt verification (master-list #146 Phase 3) to inspect the",
2051
+ "preceding Ed25519Program::verify instruction in the same tx.",
2052
+ "Address is constrained to the canonical sysvar pubkey, so the",
2053
+ "program is guaranteed to be reading the real sysvar regardless of",
2054
+ "what the client passes."
2055
+ ],
2056
+ address: "Sysvar1nstructions1111111111111111111111111"
2057
+ }
2058
+ ],
2059
+ args: [
2060
+ {
2061
+ name: "initial_commitment",
2062
+ type: {
2063
+ array: [
2064
+ "u8",
2065
+ 32
2066
+ ]
2067
+ }
2068
+ }
2069
+ ]
2070
+ },
2071
+ {
2072
+ name: "reset_identity_state",
2073
+ docs: [
2074
+ "Reset the caller's identity state to a fresh baseline.",
2075
+ "",
2076
+ "Recovery path for users whose client-side fingerprint envelope is",
2077
+ "unrecoverable (cleared site data, new device, corrupted keystore).",
2078
+ 'Without this instruction the only answer is "mint a new wallet,"',
2079
+ "which discards on-chain history and the SAS attestation. Reset",
2080
+ "rotates `current_commitment` in place and zeroes verification",
2081
+ "history so a compromised wallet cannot inherit reputation.",
2082
+ "",
2083
+ "Defenses:",
2084
+ "- Signer constraint on `authority` proves wallet ownership.",
2085
+ "- 7-day cooldown (`RESET_COOLDOWN_SECS`) bounds abuse frequency.",
2086
+ "- Full zero of `verification_count`, `trust_score`, and",
2087
+ "`recent_timestamps` means an attacker who compromises the",
2088
+ "wallet key and passes Tier 1 validation starts from zero.",
2089
+ "- Verification fee charged, matching mint/update economics.",
2090
+ "",
2091
+ "No ZK proof is consumed: there is no prior fingerprint to",
2092
+ "Hamming-compare against, and the Hamming circuit's",
2093
+ "`min_distance \u2265 3` constraint would reject a same-fingerprint",
2094
+ "proof anyway. Live-humanness evidence comes from the Tier 1",
2095
+ "validation pipeline at the SAS attestation step (handled by",
2096
+ "the off-chain executor, not this instruction)."
2097
+ ],
2098
+ discriminator: [
2099
+ 26,
2100
+ 78,
2101
+ 86,
2102
+ 143,
2103
+ 247,
2104
+ 132,
2105
+ 85,
2106
+ 203
2107
+ ],
2108
+ accounts: [
2109
+ {
2110
+ name: "authority",
2111
+ writable: true,
2112
+ signer: true
2113
+ },
2114
+ {
2115
+ name: "identity_state",
2116
+ docs: [
2117
+ "may realloc legacy-layout accounts (207 or 543 bytes) to the current",
2118
+ "551-byte layout before deserialization. PDA validated by seeds;",
2119
+ "ownership verified in instruction body after deserialization."
2120
+ ],
2121
+ writable: true,
2122
+ pda: {
2123
+ seeds: [
2124
+ {
2125
+ kind: "const",
2126
+ value: [
2127
+ 105,
2128
+ 100,
2129
+ 101,
2130
+ 110,
2131
+ 116,
2132
+ 105,
2133
+ 116,
2134
+ 121
2135
+ ]
2136
+ },
2137
+ {
2138
+ kind: "account",
2139
+ path: "authority"
2140
+ }
2141
+ ]
2142
+ }
2143
+ },
2144
+ {
2145
+ name: "protocol_config",
2146
+ docs: [
2147
+ "Supplies the verification fee amount charged on reset."
2148
+ ],
2149
+ pda: {
2150
+ seeds: [
2151
+ {
2152
+ kind: "const",
2153
+ value: [
2154
+ 112,
2155
+ 114,
2156
+ 111,
2157
+ 116,
2158
+ 111,
2159
+ 99,
2160
+ 111,
2161
+ 108,
2162
+ 95,
2163
+ 99,
2164
+ 111,
2165
+ 110,
2166
+ 102,
2167
+ 105,
2168
+ 103
2169
+ ]
2170
+ }
2171
+ ],
2172
+ program: {
2173
+ kind: "const",
2174
+ value: [
2175
+ 81,
2176
+ 130,
2177
+ 250,
2178
+ 230,
2179
+ 30,
2180
+ 253,
2181
+ 246,
2182
+ 69,
2183
+ 82,
2184
+ 96,
2185
+ 7,
2186
+ 173,
2187
+ 78,
2188
+ 160,
2189
+ 131,
2190
+ 188,
2191
+ 70,
2192
+ 106,
2193
+ 173,
2194
+ 59,
2195
+ 102,
2196
+ 163,
2197
+ 198,
2198
+ 189,
2199
+ 82,
2200
+ 37,
2201
+ 225,
2202
+ 38,
2203
+ 52,
2204
+ 233,
2205
+ 157,
2206
+ 117
2207
+ ]
2208
+ }
2209
+ }
2210
+ },
2211
+ {
2212
+ name: "treasury",
2213
+ writable: true,
2214
+ pda: {
2215
+ seeds: [
2216
+ {
2217
+ kind: "const",
2218
+ value: [
2219
+ 112,
2220
+ 114,
2221
+ 111,
2222
+ 116,
2223
+ 111,
2224
+ 99,
2225
+ 111,
2226
+ 108,
2227
+ 95,
2228
+ 116,
2229
+ 114,
2230
+ 101,
2231
+ 97,
2232
+ 115,
2233
+ 117,
2234
+ 114,
2235
+ 121
2236
+ ]
2237
+ }
2238
+ ],
2239
+ program: {
2240
+ kind: "const",
2241
+ value: [
2242
+ 81,
2243
+ 130,
2244
+ 250,
2245
+ 230,
2246
+ 30,
2247
+ 253,
2248
+ 246,
2249
+ 69,
2250
+ 82,
2251
+ 96,
2252
+ 7,
2253
+ 173,
2254
+ 78,
2255
+ 160,
2256
+ 131,
2257
+ 188,
2258
+ 70,
2259
+ 106,
2260
+ 173,
2261
+ 59,
2262
+ 102,
2263
+ 163,
2264
+ 198,
2265
+ 189,
2266
+ 82,
2267
+ 37,
2268
+ 225,
2269
+ 38,
2270
+ 52,
2271
+ 233,
2272
+ 157,
2273
+ 117
2274
+ ]
2275
+ }
2276
+ }
2277
+ },
2278
+ {
2279
+ name: "system_program",
2280
+ address: "11111111111111111111111111111111"
2281
+ }
2282
+ ],
2283
+ args: [
2284
+ {
2285
+ name: "new_commitment",
2286
+ type: {
2287
+ array: [
2288
+ "u8",
2289
+ 32
2290
+ ]
2291
+ }
2292
+ }
2293
+ ]
2294
+ },
2295
+ {
2296
+ name: "update_anchor",
2297
+ docs: [
2298
+ "Update the identity state after a successful proof verification.",
2299
+ "",
2300
+ "Trust score is computed automatically from verification history and protocol config.",
2301
+ "Handles transparent migration from old (10-slot) to new (52-slot) account layouts.",
2302
+ "",
2303
+ "Requires a matching, fresh `VerificationResult` PDA (owned by entros-verifier)",
2304
+ "whose `commitment_new` equals `new_commitment` and whose `commitment_prev`",
2305
+ "equals the identity's current stored commitment. Without this binding the",
2306
+ "instruction would accept any commitment with no biometric proof \u2014 allowing",
2307
+ "trust-score farming via per-call fee payment, which contradicts the",
2308
+ "protocol's economic deterrence model. See AUDIT.md for details.",
2309
+ "",
2310
+ "The `verification_nonce` argument supplies the challenge nonce used to",
2311
+ 'derive the VerificationResult PDA (`seeds = [b"verification", authority, nonce]`).',
2312
+ "Single-use is enforced implicitly: after this call, `current_commitment`",
2313
+ "rotates to `new_commitment`, so the consumed VerificationResult's",
2314
+ "`commitment_prev` no longer matches on any future call."
2315
+ ],
2316
+ discriminator: [
2317
+ 120,
2318
+ 192,
2319
+ 72,
2320
+ 245,
2321
+ 112,
2322
+ 246,
2323
+ 119,
2324
+ 135
2325
+ ],
2326
+ accounts: [
2327
+ {
2328
+ name: "authority",
2329
+ writable: true,
2330
+ signer: true
2331
+ },
2332
+ {
2333
+ name: "identity_state",
2334
+ docs: [
2335
+ "from old (10-slot) to new (52-slot) account layouts. PDA validated by seeds.",
2336
+ "Ownership verified in instruction body after deserialization."
2337
+ ],
2338
+ writable: true,
2339
+ pda: {
2340
+ seeds: [
2341
+ {
2342
+ kind: "const",
2343
+ value: [
2344
+ 105,
2345
+ 100,
2346
+ 101,
2347
+ 110,
2348
+ 116,
2349
+ 105,
2350
+ 116,
2351
+ 121
2352
+ ]
2353
+ },
2354
+ {
2355
+ kind: "account",
2356
+ path: "authority"
2357
+ }
2358
+ ]
2359
+ }
2360
+ },
2361
+ {
2362
+ name: "verification_result",
2363
+ docs: [
2364
+ "PDA seeds validated by Anchor; layout + owner + cross-field constraints",
2365
+ "validated in instruction body. Binds the ZK proof to this specific",
2366
+ "update \u2014 without this account, update_anchor would accept any commitment",
2367
+ "with no proof."
2368
+ ],
2369
+ pda: {
2370
+ seeds: [
2371
+ {
2372
+ kind: "const",
2373
+ value: [
2374
+ 118,
2375
+ 101,
2376
+ 114,
2377
+ 105,
2378
+ 102,
2379
+ 105,
2380
+ 99,
2381
+ 97,
2382
+ 116,
2383
+ 105,
2384
+ 111,
2385
+ 110
2386
+ ]
2387
+ },
2388
+ {
2389
+ kind: "account",
2390
+ path: "authority"
2391
+ },
2392
+ {
2393
+ kind: "arg",
2394
+ path: "verification_nonce"
2395
+ }
2396
+ ],
2397
+ program: {
2398
+ kind: "const",
2399
+ value: [
2400
+ 48,
2401
+ 50,
2402
+ 94,
2403
+ 115,
2404
+ 90,
2405
+ 162,
2406
+ 108,
2407
+ 8,
2408
+ 240,
2409
+ 151,
2410
+ 76,
2411
+ 223,
2412
+ 101,
2413
+ 176,
2414
+ 170,
2415
+ 86,
2416
+ 254,
2417
+ 247,
2418
+ 252,
2419
+ 28,
2420
+ 240,
2421
+ 145,
2422
+ 60,
2423
+ 108,
2424
+ 42,
2425
+ 129,
2426
+ 105,
2427
+ 32,
2428
+ 232,
2429
+ 212,
2430
+ 226,
2431
+ 52
2432
+ ]
2433
+ }
2434
+ }
2435
+ },
2436
+ {
2437
+ name: "protocol_config",
2438
+ docs: [
2439
+ "Validated by seeds + owner via seeds::program."
2440
+ ],
2441
+ pda: {
2442
+ seeds: [
2443
+ {
2444
+ kind: "const",
2445
+ value: [
2446
+ 112,
2447
+ 114,
2448
+ 111,
2449
+ 116,
2450
+ 111,
2451
+ 99,
2452
+ 111,
2453
+ 108,
2454
+ 95,
2455
+ 99,
2456
+ 111,
2457
+ 110,
2458
+ 102,
2459
+ 105,
2460
+ 103
2461
+ ]
2462
+ }
2463
+ ],
2464
+ program: {
2465
+ kind: "const",
2466
+ value: [
2467
+ 81,
2468
+ 130,
2469
+ 250,
2470
+ 230,
2471
+ 30,
2472
+ 253,
2473
+ 246,
2474
+ 69,
2475
+ 82,
2476
+ 96,
2477
+ 7,
2478
+ 173,
2479
+ 78,
2480
+ 160,
2481
+ 131,
2482
+ 188,
2483
+ 70,
2484
+ 106,
2485
+ 173,
2486
+ 59,
2487
+ 102,
2488
+ 163,
2489
+ 198,
2490
+ 189,
2491
+ 82,
2492
+ 37,
2493
+ 225,
2494
+ 38,
2495
+ 52,
2496
+ 233,
2497
+ 157,
2498
+ 117
2499
+ ]
2500
+ }
2501
+ }
2502
+ },
2503
+ {
2504
+ name: "treasury",
2505
+ writable: true,
2506
+ pda: {
2507
+ seeds: [
2508
+ {
2509
+ kind: "const",
2510
+ value: [
2511
+ 112,
2512
+ 114,
2513
+ 111,
2514
+ 116,
2515
+ 111,
2516
+ 99,
2517
+ 111,
2518
+ 108,
2519
+ 95,
2520
+ 116,
2521
+ 114,
2522
+ 101,
2523
+ 97,
2524
+ 115,
2525
+ 117,
2526
+ 114,
2527
+ 121
2528
+ ]
2529
+ }
2530
+ ],
2531
+ program: {
2532
+ kind: "const",
2533
+ value: [
2534
+ 81,
2535
+ 130,
2536
+ 250,
2537
+ 230,
2538
+ 30,
2539
+ 253,
2540
+ 246,
2541
+ 69,
2542
+ 82,
2543
+ 96,
2544
+ 7,
2545
+ 173,
2546
+ 78,
2547
+ 160,
2548
+ 131,
2549
+ 188,
2550
+ 70,
2551
+ 106,
2552
+ 173,
2553
+ 59,
2554
+ 102,
2555
+ 163,
2556
+ 198,
2557
+ 189,
2558
+ 82,
2559
+ 37,
2560
+ 225,
2561
+ 38,
2562
+ 52,
2563
+ 233,
2564
+ 157,
2565
+ 117
2566
+ ]
2567
+ }
2568
+ }
2569
+ },
2570
+ {
2571
+ name: "system_program",
2572
+ address: "11111111111111111111111111111111"
2573
+ }
2574
+ ],
2575
+ args: [
2576
+ {
2577
+ name: "new_commitment",
2578
+ type: {
2579
+ array: [
2580
+ "u8",
2581
+ 32
2582
+ ]
2583
+ }
2584
+ },
2585
+ {
2586
+ name: "verification_nonce",
2587
+ type: {
2588
+ array: [
2589
+ "u8",
2590
+ 32
2591
+ ]
2592
+ }
2593
+ }
2594
+ ]
2595
+ }
2596
+ ],
2597
+ accounts: [
2598
+ {
2599
+ name: "IdentityState",
2600
+ discriminator: [
2601
+ 156,
2602
+ 32,
2603
+ 87,
2604
+ 93,
2605
+ 52,
2606
+ 155,
2607
+ 248,
2608
+ 207
2609
+ ]
2610
+ }
2611
+ ],
2612
+ events: [
2613
+ {
2614
+ name: "AnchorMinted",
2615
+ discriminator: [
2616
+ 11,
2617
+ 188,
2618
+ 6,
2619
+ 169,
2620
+ 20,
2621
+ 50,
2622
+ 128,
2623
+ 172
2624
+ ]
2625
+ },
2626
+ {
2627
+ name: "AnchorReset",
2628
+ discriminator: [
2629
+ 183,
2630
+ 48,
2631
+ 146,
2632
+ 155,
2633
+ 112,
2634
+ 20,
2635
+ 140,
2636
+ 31
2637
+ ]
2638
+ },
2639
+ {
2640
+ name: "AnchorUpdated",
2641
+ discriminator: [
2642
+ 112,
2643
+ 73,
2644
+ 210,
2645
+ 183,
2646
+ 57,
2647
+ 84,
2648
+ 103,
2649
+ 59
2650
+ ]
2651
+ },
2652
+ {
2653
+ name: "MigrateIdentityEvent",
2654
+ discriminator: [
2655
+ 33,
2656
+ 239,
2657
+ 166,
2658
+ 187,
2659
+ 108,
2660
+ 47,
2661
+ 49,
2662
+ 139
2663
+ ]
2664
+ }
2665
+ ],
2666
+ errors: [
2667
+ {
2668
+ code: 6e3,
2669
+ name: "InvalidCommitment",
2670
+ msg: "Invalid commitment: must be 32 non-zero bytes"
2671
+ },
2672
+ {
2673
+ code: 6001,
2674
+ name: "Unauthorized",
2675
+ msg: "Unauthorized: caller is not the identity owner"
2676
+ },
2677
+ {
2678
+ code: 6002,
2679
+ name: "ArithmeticOverflow",
2680
+ msg: "Arithmetic overflow"
2681
+ },
2682
+ {
2683
+ code: 6003,
2684
+ name: "InvalidProtocolConfig",
2685
+ msg: "Invalid protocol config account"
2686
+ },
2687
+ {
2688
+ code: 6004,
2689
+ name: "InvalidIdentityState",
2690
+ msg: "Identity state account failed to deserialize"
2691
+ },
2692
+ {
2693
+ code: 6005,
2694
+ name: "IdentitySerializationFailed",
2695
+ msg: "Identity state account failed to serialize"
2696
+ },
2697
+ {
2698
+ code: 6006,
2699
+ name: "VerificationResultWrongOwner",
2700
+ msg: "VerificationResult account is owned by the wrong program"
2701
+ },
2702
+ {
2703
+ code: 6007,
2704
+ name: "StaleVerificationResult",
2705
+ msg: "VerificationResult account has stale layout (pre-binding-patch)"
2706
+ },
2707
+ {
2708
+ code: 6008,
2709
+ name: "VerifierMismatch",
2710
+ msg: "VerificationResult verifier does not match the signing authority"
2711
+ },
2712
+ {
2713
+ code: 6009,
2714
+ name: "ProofExpired",
2715
+ msg: "Proof is too old to consume (MAX_PROOF_AGE_SECS exceeded)"
2716
+ },
2717
+ {
2718
+ code: 6010,
2719
+ name: "CommitmentMismatch",
2720
+ msg: "Proof commitment_new does not match the submitted new_commitment"
2721
+ },
2722
+ {
2723
+ code: 6011,
2724
+ name: "PrevCommitmentMismatch",
2725
+ msg: "Proof commitment_prev does not match the identity's current_commitment"
2726
+ },
2727
+ {
2728
+ code: 6012,
2729
+ name: "ResetCooldownActive",
2730
+ msg: "Reset cooldown has not elapsed since the last reset"
2731
+ },
2732
+ {
2733
+ code: 6013,
2734
+ name: "UnauthorizedNewWallet",
2735
+ msg: "caller is not authorized by the old identity"
2736
+ },
2737
+ {
2738
+ code: 6014,
2739
+ name: "ProofFromFuture",
2740
+ msg: "VerificationResult.verified_at is in the future relative to the cluster clock"
2741
+ },
2742
+ {
2743
+ code: 6015,
2744
+ name: "MissingValidatorReceipt",
2745
+ msg: "mint_anchor expected a preceding Ed25519Program::verify instruction with a validator-signed receipt; none found"
2746
+ },
2747
+ {
2748
+ code: 6016,
2749
+ name: "ReceiptValidatorMismatch",
2750
+ msg: "Receipt was signed by a key that does not match ProtocolConfig.validator_pubkey"
2751
+ },
2752
+ {
2753
+ code: 6017,
2754
+ name: "ReceiptCommitmentMismatch",
2755
+ msg: "Receipt commitment does not match the mint_anchor commitment argument"
2756
+ },
2757
+ {
2758
+ code: 6018,
2759
+ name: "ReceiptWalletMismatch",
2760
+ msg: "Receipt wallet does not match the mint signer"
2761
+ },
2762
+ {
2763
+ code: 6019,
2764
+ name: "ReceiptExpired",
2765
+ msg: "Receipt has aged past MAX_RECEIPT_AGE_SECS"
2766
+ },
2767
+ {
2768
+ code: 6020,
2769
+ name: "ReceiptFromFuture",
2770
+ msg: "Receipt validated_at is in the future relative to the cluster clock"
2771
+ },
2772
+ {
2773
+ code: 6021,
2774
+ name: "MalformedReceiptMessage",
2775
+ msg: "Receipt message has malformed length or layout"
2776
+ }
2777
+ ],
2778
+ types: [
2779
+ {
2780
+ name: "AnchorMinted",
2781
+ type: {
2782
+ kind: "struct",
2783
+ fields: [
2784
+ {
2785
+ name: "owner",
2786
+ type: "pubkey"
2787
+ },
2788
+ {
2789
+ name: "mint",
2790
+ type: "pubkey"
2791
+ },
2792
+ {
2793
+ name: "commitment",
2794
+ type: {
2795
+ array: [
2796
+ "u8",
2797
+ 32
2798
+ ]
2799
+ }
2800
+ }
2801
+ ]
2802
+ }
2803
+ },
2804
+ {
2805
+ name: "AnchorReset",
2806
+ type: {
2807
+ kind: "struct",
2808
+ fields: [
2809
+ {
2810
+ name: "owner",
2811
+ type: "pubkey"
2812
+ },
2813
+ {
2814
+ name: "mint",
2815
+ type: "pubkey"
2816
+ },
2817
+ {
2818
+ name: "commitment",
2819
+ type: {
2820
+ array: [
2821
+ "u8",
2822
+ 32
2823
+ ]
2824
+ }
2825
+ }
2826
+ ]
2827
+ }
2828
+ },
2829
+ {
2830
+ name: "AnchorUpdated",
2831
+ type: {
2832
+ kind: "struct",
2833
+ fields: [
2834
+ {
2835
+ name: "owner",
2836
+ type: "pubkey"
2837
+ },
2838
+ {
2839
+ name: "verification_count",
2840
+ type: "u32"
2841
+ },
2842
+ {
2843
+ name: "trust_score",
2844
+ type: "u16"
2845
+ },
2846
+ {
2847
+ name: "commitment",
2848
+ type: {
2849
+ array: [
2850
+ "u8",
2851
+ 32
2852
+ ]
2853
+ }
2854
+ }
2855
+ ]
2856
+ }
2857
+ },
2858
+ {
2859
+ name: "IdentityState",
2860
+ type: {
2861
+ kind: "struct",
2862
+ fields: [
2863
+ {
2864
+ name: "owner",
2865
+ docs: [
2866
+ "The user's wallet pubkey"
2867
+ ],
2868
+ type: "pubkey"
2869
+ },
2870
+ {
2871
+ name: "creation_timestamp",
2872
+ docs: [
2873
+ "When the identity was first minted"
2874
+ ],
2875
+ type: "i64"
2876
+ },
2877
+ {
2878
+ name: "last_verification_timestamp",
2879
+ docs: [
2880
+ "Most recent successful verification"
2881
+ ],
2882
+ type: "i64"
2883
+ },
2884
+ {
2885
+ name: "verification_count",
2886
+ docs: [
2887
+ "Total successful verifications"
2888
+ ],
2889
+ type: "u32"
2890
+ },
2891
+ {
2892
+ name: "trust_score",
2893
+ docs: [
2894
+ "Computed reputation metric"
2895
+ ],
2896
+ type: "u16"
2897
+ },
2898
+ {
2899
+ name: "current_commitment",
2900
+ docs: [
2901
+ "Latest Poseidon commitment H_TBH"
2902
+ ],
2903
+ type: {
2904
+ array: [
2905
+ "u8",
2906
+ 32
2907
+ ]
2908
+ }
2909
+ },
2910
+ {
2911
+ name: "mint",
2912
+ docs: [
2913
+ "The NonTransferable mint associated with this identity"
2914
+ ],
2915
+ type: "pubkey"
2916
+ },
2917
+ {
2918
+ name: "bump",
2919
+ docs: [
2920
+ "PDA bump seed"
2921
+ ],
2922
+ type: "u8"
2923
+ },
2924
+ {
2925
+ name: "recent_timestamps",
2926
+ docs: [
2927
+ "Timestamps of last 52 verifications (newest at index 0).",
2928
+ "52 slots covers 1 year of weekly or 4+ years of monthly verifications.",
2929
+ "Older entries contribute negligible score due to exponential recency decay."
2930
+ ],
2931
+ type: {
2932
+ array: [
2933
+ "i64",
2934
+ 52
2935
+ ]
2936
+ }
2937
+ },
2938
+ {
2939
+ name: "last_reset_timestamp",
2940
+ docs: [
2941
+ "Most recent `reset_identity_state` invocation. Zero when the identity",
2942
+ "has never been reset (including freshly minted accounts and accounts",
2943
+ "created before this field existed and then realloc'd in-place)."
2944
+ ],
2945
+ type: "i64"
2946
+ },
2947
+ {
2948
+ name: "new_wallet",
2949
+ docs: [
2950
+ "new wallet for migrate_identity()"
2951
+ ],
2952
+ type: "pubkey"
2953
+ }
2954
+ ]
2955
+ }
2956
+ },
2957
+ {
2958
+ name: "MigrateIdentityEvent",
2959
+ type: {
2960
+ kind: "struct",
2961
+ fields: [
2962
+ {
2963
+ name: "wallet_old",
2964
+ type: "pubkey"
2965
+ },
2966
+ {
2967
+ name: "wallet_new",
2968
+ type: "pubkey"
2969
+ },
2970
+ {
2971
+ name: "identity_old",
2972
+ type: "pubkey"
2973
+ },
2974
+ {
2975
+ name: "identity_new",
2976
+ type: "pubkey"
2977
+ }
2978
+ ]
2979
+ }
2980
+ }
2981
+ ]
2982
+ };
2983
+
2984
+ // src/protocol/idl/entros_verifier.json
2985
+ var entros_verifier_default = {
2986
+ address: "4F97jNoxQzT2qRbkWpW3ztC3Nz2TtKj3rnKG8ExgnrfV",
2987
+ metadata: {
2988
+ name: "entros_verifier",
2989
+ version: "0.1.0",
2990
+ spec: "0.1.0",
2991
+ description: "ZK proof verification program for Entros Protocol"
2992
+ },
2993
+ instructions: [
2994
+ {
2995
+ name: "close_challenge",
2996
+ docs: [
2997
+ "Close a used or expired challenge account to reclaim rent."
2998
+ ],
2999
+ discriminator: [
3000
+ 29,
3001
+ 156,
3002
+ 109,
3003
+ 17,
3004
+ 41,
3005
+ 99,
3006
+ 71,
3007
+ 236
3008
+ ],
3009
+ accounts: [
3010
+ {
3011
+ name: "challenger",
3012
+ writable: true,
3013
+ signer: true
3014
+ },
3015
+ {
3016
+ name: "challenge",
3017
+ writable: true
3018
+ }
3019
+ ],
3020
+ args: []
3021
+ },
3022
+ {
3023
+ name: "close_verification_result",
3024
+ docs: [
3025
+ "Close a verification result account to reclaim rent."
3026
+ ],
3027
+ discriminator: [
3028
+ 202,
3029
+ 203,
3030
+ 62,
3031
+ 127,
3032
+ 7,
3033
+ 157,
3034
+ 143,
3035
+ 12
3036
+ ],
3037
+ accounts: [
3038
+ {
3039
+ name: "verifier",
3040
+ writable: true,
3041
+ signer: true
3042
+ },
3043
+ {
3044
+ name: "verification_result",
3045
+ writable: true
3046
+ }
3047
+ ],
3048
+ args: []
3049
+ },
3050
+ {
3051
+ name: "create_challenge",
3052
+ docs: [
3053
+ "Create a verification challenge with a client-generated nonce."
3054
+ ],
3055
+ discriminator: [
3056
+ 170,
3057
+ 244,
3058
+ 47,
3059
+ 1,
3060
+ 1,
3061
+ 15,
3062
+ 173,
3063
+ 239
3064
+ ],
3065
+ accounts: [
3066
+ {
3067
+ name: "challenger",
3068
+ writable: true,
3069
+ signer: true
3070
+ },
3071
+ {
3072
+ name: "challenge",
3073
+ writable: true,
3074
+ pda: {
3075
+ seeds: [
3076
+ {
3077
+ kind: "const",
3078
+ value: [
3079
+ 99,
3080
+ 104,
3081
+ 97,
3082
+ 108,
3083
+ 108,
3084
+ 101,
3085
+ 110,
3086
+ 103,
3087
+ 101
3088
+ ]
3089
+ },
3090
+ {
3091
+ kind: "account",
3092
+ path: "challenger"
3093
+ },
3094
+ {
3095
+ kind: "arg",
3096
+ path: "nonce"
3097
+ }
3098
+ ]
3099
+ }
3100
+ },
3101
+ {
3102
+ name: "system_program",
3103
+ address: "11111111111111111111111111111111"
3104
+ }
3105
+ ],
3106
+ args: [
3107
+ {
3108
+ name: "nonce",
3109
+ type: {
3110
+ array: [
3111
+ "u8",
3112
+ 32
3113
+ ]
3114
+ }
3115
+ }
3116
+ ]
3117
+ },
3118
+ {
3119
+ name: "verify_proof",
3120
+ docs: [
3121
+ "Verify a proof against a challenge.",
3122
+ "Validates the challenge is unused and not expired, runs mock verification,",
3123
+ "and stores the result."
3124
+ ],
3125
+ discriminator: [
3126
+ 217,
3127
+ 211,
3128
+ 191,
3129
+ 110,
3130
+ 144,
3131
+ 13,
3132
+ 186,
3133
+ 98
3134
+ ],
3135
+ accounts: [
3136
+ {
3137
+ name: "verifier",
3138
+ writable: true,
3139
+ signer: true
3140
+ },
3141
+ {
3142
+ name: "challenge",
3143
+ writable: true,
3144
+ pda: {
3145
+ seeds: [
3146
+ {
3147
+ kind: "const",
3148
+ value: [
3149
+ 99,
3150
+ 104,
3151
+ 97,
3152
+ 108,
3153
+ 108,
3154
+ 101,
3155
+ 110,
3156
+ 103,
3157
+ 101
3158
+ ]
3159
+ },
3160
+ {
3161
+ kind: "account",
3162
+ path: "verifier"
3163
+ },
3164
+ {
3165
+ kind: "arg",
3166
+ path: "nonce"
3167
+ }
3168
+ ]
3169
+ }
3170
+ },
3171
+ {
3172
+ name: "verification_result",
3173
+ writable: true,
3174
+ pda: {
3175
+ seeds: [
3176
+ {
3177
+ kind: "const",
3178
+ value: [
3179
+ 118,
3180
+ 101,
3181
+ 114,
3182
+ 105,
3183
+ 102,
3184
+ 105,
3185
+ 99,
3186
+ 97,
3187
+ 116,
3188
+ 105,
3189
+ 111,
3190
+ 110
3191
+ ]
3192
+ },
3193
+ {
3194
+ kind: "account",
3195
+ path: "verifier"
3196
+ },
3197
+ {
3198
+ kind: "arg",
3199
+ path: "nonce"
3200
+ }
3201
+ ]
3202
+ }
3203
+ },
3204
+ {
3205
+ name: "system_program",
3206
+ address: "11111111111111111111111111111111"
3207
+ }
3208
+ ],
3209
+ args: [
3210
+ {
3211
+ name: "proof_bytes",
3212
+ type: "bytes"
3213
+ },
3214
+ {
3215
+ name: "public_inputs",
3216
+ type: {
3217
+ vec: {
3218
+ array: [
3219
+ "u8",
3220
+ 32
3221
+ ]
3222
+ }
3223
+ }
3224
+ },
3225
+ {
3226
+ name: "nonce",
3227
+ type: {
3228
+ array: [
3229
+ "u8",
3230
+ 32
3231
+ ]
3232
+ }
3233
+ }
3234
+ ]
3235
+ }
3236
+ ],
3237
+ accounts: [
3238
+ {
3239
+ name: "Challenge",
3240
+ discriminator: [
3241
+ 119,
3242
+ 250,
3243
+ 161,
3244
+ 121,
3245
+ 119,
3246
+ 81,
3247
+ 22,
3248
+ 208
3249
+ ]
3250
+ },
3251
+ {
3252
+ name: "VerificationResult",
3253
+ discriminator: [
3254
+ 104,
3255
+ 111,
3256
+ 80,
3257
+ 172,
3258
+ 219,
3259
+ 191,
3260
+ 162,
3261
+ 38
3262
+ ]
3263
+ }
3264
+ ],
3265
+ events: [
3266
+ {
3267
+ name: "ChallengeCreated",
3268
+ discriminator: [
3269
+ 166,
3270
+ 178,
3271
+ 174,
3272
+ 178,
3273
+ 11,
3274
+ 172,
3275
+ 98,
3276
+ 243
3277
+ ]
3278
+ },
3279
+ {
3280
+ name: "VerificationComplete",
3281
+ discriminator: [
3282
+ 22,
3283
+ 74,
3284
+ 77,
3285
+ 232,
3286
+ 220,
3287
+ 46,
3288
+ 59,
3289
+ 120
3290
+ ]
3291
+ }
3292
+ ],
3293
+ errors: [
3294
+ {
3295
+ code: 6e3,
3296
+ name: "InvalidProofFormat",
3297
+ msg: "Invalid proof format"
3298
+ },
3299
+ {
3300
+ code: 6001,
3301
+ name: "ProofVerificationFailed",
3302
+ msg: "Proof verification failed"
3303
+ },
3304
+ {
3305
+ code: 6002,
3306
+ name: "ChallengeExpired",
3307
+ msg: "Challenge has expired"
3308
+ },
3309
+ {
3310
+ code: 6003,
3311
+ name: "ChallengeAlreadyUsed",
3312
+ msg: "Challenge already used"
3313
+ },
3314
+ {
3315
+ code: 6004,
3316
+ name: "InvalidPublicInputs",
3317
+ msg: "Invalid public inputs"
3318
+ },
3319
+ {
3320
+ code: 6005,
3321
+ name: "ChallengeNotUsed",
3322
+ msg: "Challenge must be used before closing"
3323
+ },
3324
+ {
3325
+ code: 6006,
3326
+ name: "InvalidNonce",
3327
+ msg: "Invalid nonce: must not be all zeros"
3328
+ },
3329
+ {
3330
+ code: 6007,
3331
+ name: "ArithmeticOverflow",
3332
+ msg: "Arithmetic overflow"
3333
+ }
3334
+ ],
3335
+ types: [
3336
+ {
3337
+ name: "Challenge",
3338
+ type: {
3339
+ kind: "struct",
3340
+ fields: [
3341
+ {
3342
+ name: "challenger",
3343
+ docs: [
3344
+ "The user who requested the challenge"
3345
+ ],
3346
+ type: "pubkey"
3347
+ },
3348
+ {
3349
+ name: "nonce",
3350
+ docs: [
3351
+ "Random nonce for anti-replay"
3352
+ ],
3353
+ type: {
3354
+ array: [
3355
+ "u8",
3356
+ 32
3357
+ ]
3358
+ }
3359
+ },
3360
+ {
3361
+ name: "created_at",
3362
+ docs: [
3363
+ "Unix timestamp when challenge was created"
3364
+ ],
3365
+ type: "i64"
3366
+ },
3367
+ {
3368
+ name: "expires_at",
3369
+ docs: [
3370
+ "Unix timestamp when challenge expires"
3371
+ ],
3372
+ type: "i64"
3373
+ },
3374
+ {
3375
+ name: "used",
3376
+ docs: [
3377
+ "Whether this challenge has been consumed"
3378
+ ],
3379
+ type: "bool"
3380
+ },
3381
+ {
3382
+ name: "bump",
3383
+ docs: [
3384
+ "PDA bump seed"
3385
+ ],
3386
+ type: "u8"
3387
+ }
3388
+ ]
3389
+ }
3390
+ },
3391
+ {
3392
+ name: "ChallengeCreated",
3393
+ type: {
3394
+ kind: "struct",
3395
+ fields: [
3396
+ {
3397
+ name: "challenger",
3398
+ type: "pubkey"
3399
+ },
3400
+ {
3401
+ name: "nonce",
3402
+ type: {
3403
+ array: [
3404
+ "u8",
3405
+ 32
3406
+ ]
3407
+ }
3408
+ },
3409
+ {
3410
+ name: "expires_at",
3411
+ type: "i64"
3412
+ }
3413
+ ]
3414
+ }
3415
+ },
3416
+ {
3417
+ name: "VerificationComplete",
3418
+ type: {
3419
+ kind: "struct",
3420
+ fields: [
3421
+ {
3422
+ name: "verifier",
3423
+ type: "pubkey"
3424
+ },
3425
+ {
3426
+ name: "is_valid",
3427
+ type: "bool"
3428
+ },
3429
+ {
3430
+ name: "nonce",
3431
+ type: {
3432
+ array: [
3433
+ "u8",
3434
+ 32
3435
+ ]
3436
+ }
3437
+ }
3438
+ ]
3439
+ }
3440
+ },
3441
+ {
3442
+ name: "VerificationResult",
3443
+ type: {
3444
+ kind: "struct",
3445
+ fields: [
3446
+ {
3447
+ name: "verifier",
3448
+ docs: [
3449
+ "Who submitted the proof"
3450
+ ],
3451
+ type: "pubkey"
3452
+ },
3453
+ {
3454
+ name: "proof_hash",
3455
+ docs: [
3456
+ "Hash of the proof bytes for audit trail"
3457
+ ],
3458
+ type: {
3459
+ array: [
3460
+ "u8",
3461
+ 32
3462
+ ]
3463
+ }
3464
+ },
3465
+ {
3466
+ name: "verified_at",
3467
+ docs: [
3468
+ "Unix timestamp of verification"
3469
+ ],
3470
+ type: "i64"
3471
+ },
3472
+ {
3473
+ name: "is_valid",
3474
+ docs: [
3475
+ "Whether the proof was valid.",
3476
+ "Always true for persisted records \u2014 invalid proofs revert the transaction",
3477
+ "and never create a VerificationResult. Retained for account layout stability."
3478
+ ],
3479
+ type: "bool"
3480
+ },
3481
+ {
3482
+ name: "challenge_nonce",
3483
+ docs: [
3484
+ "The challenge nonce that was consumed"
3485
+ ],
3486
+ type: {
3487
+ array: [
3488
+ "u8",
3489
+ 32
3490
+ ]
3491
+ }
3492
+ },
3493
+ {
3494
+ name: "bump",
3495
+ docs: [
3496
+ "PDA bump seed"
3497
+ ],
3498
+ type: "u8"
3499
+ },
3500
+ {
3501
+ name: "commitment_new",
3502
+ docs: [
3503
+ "New fingerprint commitment from public_inputs[0]. Read cross-program",
3504
+ "by entros-anchor::update_anchor to bind the proof to the identity update."
3505
+ ],
3506
+ type: {
3507
+ array: [
3508
+ "u8",
3509
+ 32
3510
+ ]
3511
+ }
3512
+ },
3513
+ {
3514
+ name: "commitment_prev",
3515
+ docs: [
3516
+ "Previous fingerprint commitment from public_inputs[1]. Read cross-program",
3517
+ "by entros-anchor::update_anchor to bind to the identity's stored commitment."
3518
+ ],
3519
+ type: {
3520
+ array: [
3521
+ "u8",
3522
+ 32
3523
+ ]
3524
+ }
3525
+ },
3526
+ {
3527
+ name: "threshold",
3528
+ docs: [
3529
+ "Hamming threshold from public_inputs[2]. Bounded at proof time to prevent",
3530
+ "attacker-chosen circuit parameters."
3531
+ ],
3532
+ type: "u16"
3533
+ },
3534
+ {
3535
+ name: "min_distance",
3536
+ docs: [
3537
+ "Hamming min_distance from public_inputs[3]. Bounded at proof time to",
3538
+ "prevent replay (Hamming=0) attacks via attacker-chosen min_distance=0."
3539
+ ],
3540
+ type: "u16"
3541
+ }
3542
+ ]
3543
+ }
3544
+ }
3545
+ ]
3546
+ };
3547
+
1276
3548
  // src/submit/receipt.ts
1277
3549
  var PUBKEY_BYTES = 32;
1278
3550
  var SIGNATURE_BYTES = 64;
@@ -1313,6 +3585,17 @@ async function buildEd25519ReceiptIx(receipt) {
1313
3585
  }
1314
3586
 
1315
3587
  // src/submit/wallet.ts
3588
+ async function confirmAndCheck(connection, signature) {
3589
+ if (!signature) {
3590
+ throw new Error("confirmAndCheck called without a transaction signature");
3591
+ }
3592
+ const confirmation = await connection.confirmTransaction(signature, "confirmed");
3593
+ if (confirmation?.value?.err != null) {
3594
+ throw new Error(
3595
+ `Transaction failed on chain: ${JSON.stringify(confirmation.value.err)} (sig=${signature})`
3596
+ );
3597
+ }
3598
+ }
1316
3599
  async function requestSasAttestation(wallet, walletAddress, relayerUrl, relayerApiKey, serverNonce) {
1317
3600
  if (!serverNonce) {
1318
3601
  sdkLog("[Entros SDK] Skipping SAS attestation: no server-issued nonce");
@@ -1455,24 +3738,14 @@ async function submitViaWallet(proof, commitment, options) {
1455
3738
  [new TextEncoder().encode("protocol_treasury")],
1456
3739
  registryProgramId
1457
3740
  );
1458
- const [verifierIdl, anchorIdl] = await Promise.all([
1459
- anchor.Program.fetchIdl(verifierProgramId, provider),
1460
- anchor.Program.fetchIdl(anchorProgramId, provider)
1461
- ]);
1462
- if (!verifierIdl) {
1463
- return {
1464
- success: false,
1465
- error: `Failed to fetch entros-verifier IDL from Solana (program ${PROGRAM_IDS.entrosVerifier}). Check your RPC endpoint is reachable and on the correct cluster.`
1466
- };
1467
- }
1468
- if (!anchorIdl) {
1469
- return {
1470
- success: false,
1471
- error: `Failed to fetch entros-anchor IDL from Solana (program ${PROGRAM_IDS.entrosAnchor}). Check your RPC endpoint is reachable and on the correct cluster.`
1472
- };
1473
- }
1474
- const verifierProgram = new anchor.Program(verifierIdl, provider);
1475
- const anchorProgram = new anchor.Program(anchorIdl, provider);
3741
+ const verifierProgram = new anchor.Program(
3742
+ entros_verifier_default,
3743
+ provider
3744
+ );
3745
+ const anchorProgram = new anchor.Program(
3746
+ entros_anchor_default,
3747
+ provider
3748
+ );
1476
3749
  const { Buffer: SolBuffer } = await import("buffer");
1477
3750
  const createChallengeIx = await verifierProgram.methods.createChallenge(nonce).accounts({
1478
3751
  challenger: provider.wallet.publicKey,
@@ -1507,16 +3780,12 @@ async function submitViaWallet(proof, commitment, options) {
1507
3780
  txSig = await options.wallet.sendTransaction(tx, options.connection, {
1508
3781
  skipPreflight: true
1509
3782
  });
1510
- await options.connection.confirmTransaction(txSig, "confirmed");
3783
+ await confirmAndCheck(options.connection, txSig);
1511
3784
  } else {
1512
- const anchorIdl = await anchor.Program.fetchIdl(anchorProgramId, provider);
1513
- if (!anchorIdl) {
1514
- return {
1515
- success: false,
1516
- error: `Failed to fetch entros-anchor IDL from Solana (program ${PROGRAM_IDS.entrosAnchor}). Check your RPC endpoint is reachable and on the correct cluster.`
1517
- };
1518
- }
1519
- const anchorProgram = new anchor.Program(anchorIdl, provider);
3785
+ const anchorProgram = new anchor.Program(
3786
+ entros_anchor_default,
3787
+ provider
3788
+ );
1520
3789
  const [identityPda] = PublicKey.findProgramAddressSync(
1521
3790
  [new TextEncoder().encode("identity"), provider.wallet.publicKey.toBuffer()],
1522
3791
  anchorProgramId
@@ -1589,7 +3858,7 @@ async function submitViaWallet(proof, commitment, options) {
1589
3858
  txSig = await options.wallet.sendTransaction(tx, options.connection, {
1590
3859
  skipPreflight: true
1591
3860
  });
1592
- await options.connection.confirmTransaction(txSig, "confirmed");
3861
+ await confirmAndCheck(options.connection, txSig);
1593
3862
  }
1594
3863
  const attestationTx = options.relayerUrl ? await requestSasAttestation(
1595
3864
  options.wallet,
@@ -1626,14 +3895,10 @@ async function submitResetViaWallet(commitment, options) {
1626
3895
  [new TextEncoder().encode("protocol_treasury")],
1627
3896
  registryProgramId
1628
3897
  );
1629
- const anchorIdl = await anchor.Program.fetchIdl(anchorProgramId, provider);
1630
- if (!anchorIdl) {
1631
- return {
1632
- success: false,
1633
- error: `Failed to fetch entros-anchor IDL from Solana (program ${PROGRAM_IDS.entrosAnchor}). Check your RPC endpoint is reachable and on the correct cluster.`
1634
- };
1635
- }
1636
- const anchorProgram = new anchor.Program(anchorIdl, provider);
3898
+ const anchorProgram = new anchor.Program(
3899
+ entros_anchor_default,
3900
+ provider
3901
+ );
1637
3902
  const resetIx = await anchorProgram.methods.resetIdentityState(Array.from(commitment)).accounts({
1638
3903
  authority: provider.wallet.publicKey,
1639
3904
  identityState: identityPda,
@@ -1651,7 +3916,7 @@ async function submitResetViaWallet(commitment, options) {
1651
3916
  options.connection,
1652
3917
  { skipPreflight: true }
1653
3918
  );
1654
- await options.connection.confirmTransaction(txSig, "confirmed");
3919
+ await confirmAndCheck(options.connection, txSig);
1655
3920
  const attestationTx = options.relayerUrl ? await requestSasAttestation(
1656
3921
  options.wallet,
1657
3922
  provider.wallet.publicKey.toBase58(),
@@ -1861,11 +4126,7 @@ async function fetchIdentityState(walletPubkey, connection) {
1861
4126
  );
1862
4127
  const accountInfo = await connection.getAccountInfo(identityPda);
1863
4128
  if (!accountInfo) return null;
1864
- const idl = await anchor.Program.fetchIdl(programId, {
1865
- connection
1866
- });
1867
- if (!idl) return null;
1868
- const coder = new anchor.BorshAccountsCoder(idl);
4129
+ const coder = new anchor.BorshAccountsCoder(entros_anchor_default);
1869
4130
  const decoded = coder.decode("identityState", accountInfo.data);
1870
4131
  return {
1871
4132
  owner: decoded.owner.toBase58(),
@@ -1973,10 +4234,13 @@ async function extractFeatures(data) {
1973
4234
  const { features: audioFeatures, f0Contour } = await extractSpeakerFeaturesDetailed(
1974
4235
  data.audio
1975
4236
  );
4237
+ await yieldToMainThread();
1976
4238
  const hasMotion = data.motion.length >= MIN_MOTION_SAMPLES;
1977
4239
  const hasTouch = data.touch.length >= MIN_TOUCH_SAMPLES;
1978
4240
  const motionFeatures = hasMotion && hasTouch ? extractMouseDynamics(data.touch) : hasMotion ? extractMotionFeatures(data.motion) : extractMouseDynamics(data.touch);
4241
+ await yieldToMainThread();
1979
4242
  const touchFeatures = extractTouchFeatures(data.touch);
4243
+ await yieldToMainThread();
1980
4244
  const accelMagnitude = hasMotion && f0Contour.length > 0 ? extractAccelerationMagnitude(data.motion, f0Contour.length) : [];
1981
4245
  return {
1982
4246
  raw: fuseRawFeatures(audioFeatures, motionFeatures, touchFeatures),
@@ -1990,6 +4254,7 @@ var MIN_MOTION_SAMPLES = 10;
1990
4254
  var MIN_TOUCH_SAMPLES = 10;
1991
4255
  async function extractFingerprintAndValidate(sensorData, config, walletAddress, onProgress) {
1992
4256
  onProgress?.("Extracting features...");
4257
+ await yieldToMainThread();
1993
4258
  const {
1994
4259
  raw: features,
1995
4260
  normalized: normalizedFeatures,
@@ -2004,6 +4269,7 @@ async function extractFingerprintAndValidate(sensorData, config, walletAddress,
2004
4269
  const tbh = await generateTBH(fingerprint);
2005
4270
  let signedReceipt;
2006
4271
  onProgress?.("Validating...");
4272
+ await yieldToMainThread();
2007
4273
  if (config.relayerUrl && walletAddress) {
2008
4274
  try {
2009
4275
  const baseUrl = new URL(config.relayerUrl);