ox 0.10.2 → 0.10.4

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.
@@ -1,4 +1,13 @@
1
- import { Hex, PublicKey, Secp256k1, Signature, WebAuthnP256 } from 'ox'
1
+ import {
2
+ Address,
3
+ Hex,
4
+ P256,
5
+ PublicKey,
6
+ Secp256k1,
7
+ Signature,
8
+ WebAuthnP256,
9
+ WebCryptoP256,
10
+ } from 'ox'
2
11
  import { describe, expect, test } from 'vitest'
3
12
  import * as SignatureEnvelope from './SignatureEnvelope.js'
4
13
 
@@ -477,6 +486,24 @@ describe('deserialize', () => {
477
486
  })
478
487
  })
479
488
 
489
+ test('behavior: deserializes signature with magic identifier', () => {
490
+ const serialized = SignatureEnvelope.serialize(
491
+ { signature: signature_secp256k1, type: 'secp256k1' },
492
+ { magic: true },
493
+ )
494
+
495
+ const envelope = SignatureEnvelope.deserialize(serialized)
496
+
497
+ expect(envelope).toMatchObject({
498
+ signature: {
499
+ r: signature_secp256k1.r,
500
+ s: signature_secp256k1.s,
501
+ yParity: signature_secp256k1.yParity,
502
+ },
503
+ type: 'secp256k1',
504
+ })
505
+ })
506
+
480
507
  test('error: throws on invalid size', () => {
481
508
  expect(() =>
482
509
  SignatureEnvelope.deserialize('0xdeadbeef'),
@@ -520,6 +547,26 @@ describe('deserialize', () => {
520
547
  })
521
548
  })
522
549
 
550
+ test('behavior: deserializes P256 signature with magic identifier', () => {
551
+ const serialized = SignatureEnvelope.serialize(signature_p256, {
552
+ magic: true,
553
+ })
554
+ const deserialized = SignatureEnvelope.deserialize(serialized)
555
+
556
+ expect(deserialized).toMatchObject({
557
+ signature: {
558
+ r: signature_p256.signature.r,
559
+ s: signature_p256.signature.s,
560
+ },
561
+ publicKey: {
562
+ x: signature_p256.publicKey.x,
563
+ y: signature_p256.publicKey.y,
564
+ },
565
+ prehash: signature_p256.prehash,
566
+ type: 'p256',
567
+ })
568
+ })
569
+
523
570
  test('error: throws on invalid P256 signature length', () => {
524
571
  // P256 signature with wrong length (should be 130 bytes total, but only 100)
525
572
  const invalidSig = `0x01${'00'.repeat(100)}` as `0x${string}`
@@ -557,6 +604,29 @@ describe('deserialize', () => {
557
604
  })
558
605
  })
559
606
 
607
+ test('behavior: deserializes WebAuthn signature with magic identifier', () => {
608
+ const serialized = SignatureEnvelope.serialize(signature_webauthn, {
609
+ magic: true,
610
+ })
611
+ const deserialized = SignatureEnvelope.deserialize(serialized)
612
+
613
+ expect(deserialized).toMatchObject({
614
+ signature: {
615
+ r: signature_webauthn.signature.r,
616
+ s: signature_webauthn.signature.s,
617
+ },
618
+ publicKey: {
619
+ x: signature_webauthn.publicKey.x,
620
+ y: signature_webauthn.publicKey.y,
621
+ },
622
+ metadata: {
623
+ authenticatorData: signature_webauthn.metadata.authenticatorData,
624
+ clientDataJSON: signature_webauthn.metadata.clientDataJSON,
625
+ },
626
+ type: 'webAuthn',
627
+ })
628
+ })
629
+
560
630
  test('error: throws on invalid WebAuthn signature length', () => {
561
631
  // WebAuthn signature too short (must be at least 129 bytes: 1 type + 128 signature data)
562
632
  const invalidSig = `0x02${'00'.repeat(100)}` as const
@@ -676,6 +746,20 @@ describe('deserialize', () => {
676
746
  `)
677
747
  })
678
748
 
749
+ test('behavior: deserializes keychain signature with magic identifier', () => {
750
+ const serialized = SignatureEnvelope.serialize(
751
+ signature_keychain_secp256k1,
752
+ { magic: true },
753
+ )
754
+ const deserialized = SignatureEnvelope.deserialize(serialized)
755
+
756
+ expect(deserialized).toMatchObject({
757
+ userAddress: signature_keychain_secp256k1.userAddress,
758
+ inner: SignatureEnvelope.from(signature_secp256k1),
759
+ type: 'keychain',
760
+ })
761
+ })
762
+
679
763
  test('error: throws on invalid keychain signature length', () => {
680
764
  // Keychain signature too short (must be at least 21 bytes: 1 type + 20 address)
681
765
  const invalidSig = `0x03${'00'.repeat(10)}` as const
@@ -916,6 +1000,20 @@ describe('serialize', () => {
916
1000
 
917
1001
  expect(serialized).toBe(Signature.toHex(signature_secp256k1))
918
1002
  })
1003
+
1004
+ test('behavior: serializes with magic identifier', () => {
1005
+ const envelope: SignatureEnvelope.SignatureEnvelope = {
1006
+ signature: signature_secp256k1,
1007
+ type: 'secp256k1',
1008
+ }
1009
+
1010
+ const serialized = SignatureEnvelope.serialize(envelope, { magic: true })
1011
+
1012
+ expect(serialized.endsWith(SignatureEnvelope.magicBytes.slice(2))).toBe(
1013
+ true,
1014
+ )
1015
+ expect(Hex.size(serialized)).toBe(65 + 32) // signature + magic identifier
1016
+ })
919
1017
  })
920
1018
 
921
1019
  describe('p256', () => {
@@ -936,6 +1034,17 @@ describe('serialize', () => {
936
1034
  // Last byte should be 0x00 for false
937
1035
  expect(serialized.slice(-2)).toBe('00')
938
1036
  })
1037
+
1038
+ test('behavior: serializes with magic identifier', () => {
1039
+ const serialized = SignatureEnvelope.serialize(signature_p256, {
1040
+ magic: true,
1041
+ })
1042
+
1043
+ expect(serialized.endsWith(SignatureEnvelope.magicBytes.slice(2))).toBe(
1044
+ true,
1045
+ )
1046
+ expect(Hex.size(serialized)).toBe(130 + 32) // signature + magic identifier
1047
+ })
939
1048
  })
940
1049
 
941
1050
  describe('webAuthn', () => {
@@ -966,6 +1075,23 @@ describe('serialize', () => {
966
1075
  signature_webauthn.metadata.clientDataJSON,
967
1076
  )
968
1077
  })
1078
+
1079
+ test('behavior: serializes with magic identifier', () => {
1080
+ const serialized = SignatureEnvelope.serialize(signature_webauthn, {
1081
+ magic: true,
1082
+ })
1083
+
1084
+ expect(serialized.endsWith(SignatureEnvelope.magicBytes.slice(2))).toBe(
1085
+ true,
1086
+ )
1087
+
1088
+ const authDataLength =
1089
+ (signature_webauthn.metadata.authenticatorData.length - 2) / 2
1090
+ const clientDataLength = signature_webauthn.metadata.clientDataJSON.length
1091
+ const expectedSize = 1 + authDataLength + clientDataLength + 128 + 32 // type + data + signature components + magic
1092
+
1093
+ expect(Hex.size(serialized)).toBe(expectedSize)
1094
+ })
969
1095
  })
970
1096
 
971
1097
  describe('keychain', () => {
@@ -1043,6 +1169,18 @@ describe('serialize', () => {
1043
1169
  },
1044
1170
  })
1045
1171
  })
1172
+
1173
+ test('behavior: serializes with magic identifier', () => {
1174
+ const serialized = SignatureEnvelope.serialize(
1175
+ signature_keychain_secp256k1,
1176
+ { magic: true },
1177
+ )
1178
+
1179
+ expect(serialized.endsWith(SignatureEnvelope.magicBytes.slice(2))).toBe(
1180
+ true,
1181
+ )
1182
+ expect(Hex.size(serialized)).toBe(1 + 20 + 65 + 32) // type + address + secp256k1 + magic
1183
+ })
1046
1184
  })
1047
1185
 
1048
1186
  describe('roundtrip', () => {
@@ -1065,6 +1203,27 @@ describe('serialize', () => {
1065
1203
  type: 'secp256k1',
1066
1204
  })
1067
1205
  })
1206
+
1207
+ test('behavior: roundtrips serialize with magic -> deserialize', () => {
1208
+ const envelope: SignatureEnvelope.Secp256k1 = {
1209
+ signature: signature_secp256k1,
1210
+ type: 'secp256k1',
1211
+ }
1212
+
1213
+ const serialized = SignatureEnvelope.serialize(envelope, {
1214
+ magic: true,
1215
+ })
1216
+ const deserialized = SignatureEnvelope.deserialize(serialized)
1217
+
1218
+ expect(deserialized).toMatchObject({
1219
+ signature: {
1220
+ r: signature_secp256k1.r,
1221
+ s: signature_secp256k1.s,
1222
+ yParity: signature_secp256k1.yParity,
1223
+ },
1224
+ type: 'secp256k1',
1225
+ })
1226
+ })
1068
1227
  })
1069
1228
 
1070
1229
  describe('p256', () => {
@@ -1093,6 +1252,26 @@ describe('serialize', () => {
1093
1252
 
1094
1253
  expect(deserialized.prehash).toBe(false)
1095
1254
  })
1255
+
1256
+ test('behavior: roundtrips serialize with magic -> deserialize', () => {
1257
+ const serialized = SignatureEnvelope.serialize(signature_p256, {
1258
+ magic: true,
1259
+ })
1260
+ const deserialized = SignatureEnvelope.deserialize(serialized)
1261
+
1262
+ expect(deserialized).toMatchObject({
1263
+ signature: {
1264
+ r: signature_p256.signature.r,
1265
+ s: signature_p256.signature.s,
1266
+ },
1267
+ publicKey: {
1268
+ x: signature_p256.publicKey.x,
1269
+ y: signature_p256.publicKey.y,
1270
+ },
1271
+ prehash: signature_p256.prehash,
1272
+ type: 'p256',
1273
+ })
1274
+ })
1096
1275
  })
1097
1276
 
1098
1277
  describe('webAuthn', () => {
@@ -1137,6 +1316,29 @@ describe('serialize', () => {
1137
1316
 
1138
1317
  expect(deserialized.metadata?.clientDataJSON).toBe(longClientData)
1139
1318
  })
1319
+
1320
+ test('behavior: roundtrips serialize with magic -> deserialize', () => {
1321
+ const serialized = SignatureEnvelope.serialize(signature_webauthn, {
1322
+ magic: true,
1323
+ })
1324
+ const deserialized = SignatureEnvelope.deserialize(serialized)
1325
+
1326
+ expect(deserialized).toMatchObject({
1327
+ signature: {
1328
+ r: signature_webauthn.signature.r,
1329
+ s: signature_webauthn.signature.s,
1330
+ },
1331
+ publicKey: {
1332
+ x: signature_webauthn.publicKey.x,
1333
+ y: signature_webauthn.publicKey.y,
1334
+ },
1335
+ metadata: {
1336
+ authenticatorData: signature_webauthn.metadata.authenticatorData,
1337
+ clientDataJSON: signature_webauthn.metadata.clientDataJSON,
1338
+ },
1339
+ type: 'webAuthn',
1340
+ })
1341
+ })
1140
1342
  })
1141
1343
 
1142
1344
  describe('keychain', () => {
@@ -1203,6 +1405,69 @@ describe('serialize', () => {
1203
1405
  }
1204
1406
  `)
1205
1407
  })
1408
+
1409
+ test('behavior: roundtrips serialize with magic -> deserialize with secp256k1 inner', () => {
1410
+ const serialized = SignatureEnvelope.serialize(
1411
+ signature_keychain_secp256k1,
1412
+ { magic: true },
1413
+ )
1414
+ const deserialized = SignatureEnvelope.deserialize(serialized)
1415
+
1416
+ expect(deserialized).toMatchObject(signature_keychain_secp256k1)
1417
+ })
1418
+
1419
+ test('behavior: roundtrips serialize with magic -> deserialize with p256 inner', () => {
1420
+ const serialized = SignatureEnvelope.serialize(
1421
+ signature_keychain_p256,
1422
+ { magic: true },
1423
+ )
1424
+ const deserialized = SignatureEnvelope.deserialize(serialized)
1425
+
1426
+ expect(deserialized).toMatchObject({
1427
+ type: 'keychain',
1428
+ userAddress: signature_keychain_p256.userAddress,
1429
+ inner: {
1430
+ type: 'p256',
1431
+ prehash: signature_p256.prehash,
1432
+ publicKey: {
1433
+ x: signature_p256.publicKey.x,
1434
+ y: signature_p256.publicKey.y,
1435
+ },
1436
+ signature: {
1437
+ r: signature_p256.signature.r,
1438
+ s: signature_p256.signature.s,
1439
+ },
1440
+ },
1441
+ })
1442
+ })
1443
+
1444
+ test('behavior: roundtrips serialize with magic -> deserialize with webAuthn inner', () => {
1445
+ const serialized = SignatureEnvelope.serialize(
1446
+ signature_keychain_webauthn,
1447
+ { magic: true },
1448
+ )
1449
+ const deserialized = SignatureEnvelope.deserialize(serialized)
1450
+
1451
+ expect(deserialized).toMatchObject({
1452
+ type: 'keychain',
1453
+ userAddress: signature_keychain_webauthn.userAddress,
1454
+ inner: {
1455
+ type: 'webAuthn',
1456
+ metadata: {
1457
+ authenticatorData: signature_webauthn.metadata.authenticatorData,
1458
+ clientDataJSON: signature_webauthn.metadata.clientDataJSON,
1459
+ },
1460
+ publicKey: {
1461
+ x: signature_webauthn.publicKey.x,
1462
+ y: signature_webauthn.publicKey.y,
1463
+ },
1464
+ signature: {
1465
+ r: signature_webauthn.signature.r,
1466
+ s: signature_webauthn.signature.s,
1467
+ },
1468
+ },
1469
+ })
1470
+ })
1206
1471
  })
1207
1472
  })
1208
1473
 
@@ -1326,6 +1591,294 @@ describe('validate', () => {
1326
1591
  })
1327
1592
  })
1328
1593
 
1594
+ describe('verify', () => {
1595
+ describe('secp256k1', () => {
1596
+ test('behavior: verifies valid signature with publicKey', () => {
1597
+ const privateKey = Secp256k1.randomPrivateKey()
1598
+ const publicKey = Secp256k1.getPublicKey({ privateKey })
1599
+ const payload = '0xdeadbeef' as const
1600
+
1601
+ const signature = Secp256k1.sign({ payload, privateKey })
1602
+ const envelope = SignatureEnvelope.from(signature)
1603
+
1604
+ expect(
1605
+ SignatureEnvelope.verify(envelope, {
1606
+ payload,
1607
+ publicKey,
1608
+ }),
1609
+ ).toBe(true)
1610
+ })
1611
+
1612
+ test('behavior: verifies valid signature with address', () => {
1613
+ const privateKey = Secp256k1.randomPrivateKey()
1614
+ const publicKey = Secp256k1.getPublicKey({ privateKey })
1615
+ const address = Address.fromPublicKey(publicKey)
1616
+ const payload = '0xdeadbeef' as const
1617
+
1618
+ const signature = Secp256k1.sign({ payload, privateKey })
1619
+ const envelope = SignatureEnvelope.from(signature)
1620
+
1621
+ expect(
1622
+ SignatureEnvelope.verify(envelope, {
1623
+ payload,
1624
+ address,
1625
+ }),
1626
+ ).toBe(true)
1627
+ })
1628
+
1629
+ test('behavior: returns false for wrong publicKey', () => {
1630
+ const privateKey = Secp256k1.randomPrivateKey()
1631
+ const wrongPrivateKey = Secp256k1.randomPrivateKey()
1632
+ const wrongPublicKey = Secp256k1.getPublicKey({
1633
+ privateKey: wrongPrivateKey,
1634
+ })
1635
+ const payload = '0xdeadbeef' as const
1636
+
1637
+ const signature = Secp256k1.sign({ payload, privateKey })
1638
+ const envelope = SignatureEnvelope.from(signature)
1639
+
1640
+ expect(
1641
+ SignatureEnvelope.verify(envelope, {
1642
+ payload,
1643
+ publicKey: wrongPublicKey,
1644
+ }),
1645
+ ).toBe(false)
1646
+ })
1647
+
1648
+ test('behavior: returns false for wrong payload', () => {
1649
+ const privateKey = Secp256k1.randomPrivateKey()
1650
+ const publicKey = Secp256k1.getPublicKey({ privateKey })
1651
+ const payload = '0xdeadbeef' as const
1652
+
1653
+ const signature = Secp256k1.sign({ payload, privateKey })
1654
+ const envelope = SignatureEnvelope.from(signature)
1655
+
1656
+ expect(
1657
+ SignatureEnvelope.verify(envelope, {
1658
+ payload: '0xcafebabe',
1659
+ publicKey,
1660
+ }),
1661
+ ).toBe(false)
1662
+ })
1663
+ })
1664
+
1665
+ describe('p256', () => {
1666
+ test('behavior: verifies valid signature with publicKey', () => {
1667
+ const privateKey = P256.randomPrivateKey()
1668
+ const publicKey = P256.getPublicKey({ privateKey })
1669
+ const payload = '0xdeadbeef' as const
1670
+
1671
+ const signature = P256.sign({ payload, privateKey })
1672
+ const envelope = SignatureEnvelope.from({
1673
+ prehash: false,
1674
+ publicKey,
1675
+ signature,
1676
+ })
1677
+
1678
+ expect(
1679
+ SignatureEnvelope.verify(envelope, {
1680
+ payload,
1681
+ publicKey,
1682
+ }),
1683
+ ).toBe(true)
1684
+ })
1685
+
1686
+ test('behavior: verifies valid signature with address', () => {
1687
+ const privateKey = P256.randomPrivateKey()
1688
+ const publicKey = P256.getPublicKey({ privateKey })
1689
+ const address = Address.fromPublicKey(publicKey)
1690
+ const payload = '0xdeadbeef' as const
1691
+
1692
+ const signature = P256.sign({ payload, privateKey })
1693
+ const envelope = SignatureEnvelope.from({
1694
+ prehash: false,
1695
+ publicKey,
1696
+ signature,
1697
+ })
1698
+
1699
+ expect(
1700
+ SignatureEnvelope.verify(envelope, {
1701
+ payload,
1702
+ address,
1703
+ }),
1704
+ ).toBe(true)
1705
+ })
1706
+
1707
+ test('behavior: returns false for mismatched publicKey', () => {
1708
+ const privateKey = P256.randomPrivateKey()
1709
+ const publicKey = P256.getPublicKey({ privateKey })
1710
+ const wrongPrivateKey = P256.randomPrivateKey()
1711
+ const wrongPublicKey = P256.getPublicKey({ privateKey: wrongPrivateKey })
1712
+ const payload = '0xdeadbeef' as const
1713
+
1714
+ const signature = P256.sign({ payload, privateKey })
1715
+ const envelope = SignatureEnvelope.from({
1716
+ prehash: false,
1717
+ publicKey,
1718
+ signature,
1719
+ })
1720
+
1721
+ expect(
1722
+ SignatureEnvelope.verify(envelope, {
1723
+ payload,
1724
+ publicKey: wrongPublicKey,
1725
+ }),
1726
+ ).toBe(false)
1727
+ })
1728
+
1729
+ test('behavior: returns false for wrong payload', () => {
1730
+ const privateKey = P256.randomPrivateKey()
1731
+ const publicKey = P256.getPublicKey({ privateKey })
1732
+ const payload = '0xdeadbeef' as const
1733
+
1734
+ const signature = P256.sign({ payload, privateKey })
1735
+ const envelope = SignatureEnvelope.from({
1736
+ prehash: false,
1737
+ publicKey,
1738
+ signature,
1739
+ })
1740
+
1741
+ expect(
1742
+ SignatureEnvelope.verify(envelope, {
1743
+ payload: '0xcafebabe',
1744
+ publicKey,
1745
+ }),
1746
+ ).toBe(false)
1747
+ })
1748
+ })
1749
+
1750
+ describe('webCryptoP256', () => {
1751
+ test('behavior: verifies valid signature with publicKey', async () => {
1752
+ const { privateKey, publicKey } = await WebCryptoP256.createKeyPair()
1753
+ const payload = '0xdeadbeef' as const
1754
+
1755
+ const signature = await WebCryptoP256.sign({ payload, privateKey })
1756
+ const envelope = SignatureEnvelope.from({
1757
+ prehash: true,
1758
+ publicKey,
1759
+ signature,
1760
+ })
1761
+
1762
+ expect(
1763
+ SignatureEnvelope.verify(envelope, {
1764
+ payload,
1765
+ publicKey,
1766
+ }),
1767
+ ).toBe(true)
1768
+ })
1769
+
1770
+ test('behavior: verifies valid signature with address', async () => {
1771
+ const { privateKey, publicKey } = await WebCryptoP256.createKeyPair()
1772
+ const address = Address.fromPublicKey(publicKey)
1773
+ const payload = '0xdeadbeef' as const
1774
+
1775
+ const signature = await WebCryptoP256.sign({ payload, privateKey })
1776
+ const envelope = SignatureEnvelope.from({
1777
+ prehash: true,
1778
+ publicKey,
1779
+ signature,
1780
+ })
1781
+
1782
+ expect(
1783
+ SignatureEnvelope.verify(envelope, {
1784
+ payload,
1785
+ address,
1786
+ }),
1787
+ ).toBe(true)
1788
+ })
1789
+
1790
+ test('behavior: returns false for mismatched publicKey', async () => {
1791
+ const { privateKey, publicKey } = await WebCryptoP256.createKeyPair()
1792
+ const { publicKey: wrongPublicKey } = await WebCryptoP256.createKeyPair()
1793
+ const payload = '0xdeadbeef' as const
1794
+
1795
+ const signature = await WebCryptoP256.sign({ payload, privateKey })
1796
+ const envelope = SignatureEnvelope.from({
1797
+ prehash: true,
1798
+ publicKey,
1799
+ signature,
1800
+ })
1801
+
1802
+ expect(
1803
+ SignatureEnvelope.verify(envelope, {
1804
+ payload,
1805
+ publicKey: wrongPublicKey,
1806
+ }),
1807
+ ).toBe(false)
1808
+ })
1809
+
1810
+ test('behavior: returns false for wrong payload', async () => {
1811
+ const { privateKey, publicKey } = await WebCryptoP256.createKeyPair()
1812
+ const payload = '0xdeadbeef' as const
1813
+
1814
+ const signature = await WebCryptoP256.sign({ payload, privateKey })
1815
+ const envelope = SignatureEnvelope.from({
1816
+ prehash: true,
1817
+ publicKey,
1818
+ signature,
1819
+ })
1820
+
1821
+ expect(
1822
+ SignatureEnvelope.verify(envelope, {
1823
+ payload: '0xcafebabe',
1824
+ publicKey,
1825
+ }),
1826
+ ).toBe(false)
1827
+ })
1828
+ })
1829
+
1830
+ describe('webAuthn', () => {
1831
+ test('behavior: returns false for mismatched publicKey', () => {
1832
+ const wrongPrivateKey = P256.randomPrivateKey()
1833
+ const wrongPublicKey = P256.getPublicKey({ privateKey: wrongPrivateKey })
1834
+ const payload = '0xdeadbeef' as const
1835
+
1836
+ expect(
1837
+ SignatureEnvelope.verify(signature_webauthn, {
1838
+ payload,
1839
+ publicKey: wrongPublicKey,
1840
+ }),
1841
+ ).toBe(false)
1842
+ })
1843
+
1844
+ test('behavior: returns false for mismatched address', () => {
1845
+ const wrongPrivateKey = P256.randomPrivateKey()
1846
+ const wrongPublicKey = P256.getPublicKey({ privateKey: wrongPrivateKey })
1847
+ const wrongAddress = Address.fromPublicKey(wrongPublicKey)
1848
+ const payload = '0xdeadbeef' as const
1849
+
1850
+ expect(
1851
+ SignatureEnvelope.verify(signature_webauthn, {
1852
+ payload,
1853
+ address: wrongAddress,
1854
+ }),
1855
+ ).toBe(false)
1856
+ })
1857
+ })
1858
+
1859
+ describe('keychain', () => {
1860
+ test('behavior: returns false for keychain signatures', () => {
1861
+ const privateKey = Secp256k1.randomPrivateKey()
1862
+ const secp256k1PublicKey = Secp256k1.getPublicKey({ privateKey })
1863
+ const payload = '0xdeadbeef' as const
1864
+
1865
+ const signature = Secp256k1.sign({ payload, privateKey })
1866
+ const innerEnvelope = SignatureEnvelope.from(signature)
1867
+ const envelope = SignatureEnvelope.from({
1868
+ userAddress: '0x1234567890123456789012345678901234567890',
1869
+ inner: innerEnvelope,
1870
+ })
1871
+
1872
+ expect(
1873
+ SignatureEnvelope.verify(envelope, {
1874
+ payload,
1875
+ publicKey: secp256k1PublicKey,
1876
+ }),
1877
+ ).toBe(false)
1878
+ })
1879
+ })
1880
+ })
1881
+
1329
1882
  describe('fromRpc', () => {
1330
1883
  describe('secp256k1', () => {
1331
1884
  test('behavior: converts RPC secp256k1 signature', () => {