diff --git a/.changeset/polite-experts-punch.md b/.changeset/polite-experts-punch.md new file mode 100644 index 0000000..d8c1482 --- /dev/null +++ b/.changeset/polite-experts-punch.md @@ -0,0 +1,5 @@ +--- +"@openfort/react-native": patch +--- + +add passkey support diff --git a/package.json b/package.json index 79b8917..d68e5ca 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,8 @@ } }, "dependencies": { - "@openfort/openfort-js": "^1.1.4" + "@openfort/openfort-js": "^1.1.5", + "react-native-passkeys": "0.4.0" }, "peerDependencies": { "expo-apple-authentication": "*", @@ -94,7 +95,10 @@ "size-limit": [ { "path": "dist/index.js", - "limit": "250 KB" + "limit": "250 KB", + "ignore": [ + "expo-modules-core" + ] } ], "pnpm": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae9c7dd..5335f7d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,18 +13,21 @@ importers: .: dependencies: '@openfort/openfort-js': - specifier: ^1.1.4 - version: 1.1.4 + specifier: ^1.1.5 + version: 1.1.5 + react-native-passkeys: + specifier: 0.4.0 + version: 0.4.0(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) devDependencies: '@biomejs/biome': specifier: ^2.2.4 - version: 2.3.11 + version: 2.3.14 '@changesets/changelog-github': specifier: ^0.5.1 version: 0.5.2 '@changesets/cli': specifier: ^2.29.7 - version: 2.29.8(@types/node@25.0.9) + version: 2.29.8(@types/node@25.2.0) '@size-limit/preset-small-lib': specifier: ^11.2.0 version: 11.2.0(size-limit@11.2.0) @@ -36,7 +39,7 @@ importers: version: 5.7.1 expo-apple-authentication: specifier: ^7.2.4 - version: 7.2.4(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1)) + version: 7.2.4(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1)) expo-application: specifier: ^6.1.4 version: 6.1.5 @@ -45,25 +48,25 @@ importers: version: 14.0.2 expo-linking: specifier: ^7.1.5 - version: 7.1.7(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) + version: 7.1.7(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) expo-secure-store: specifier: ^14.2.3 version: 14.2.4 expo-web-browser: specifier: ^14.1.6 - version: 14.2.0(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1)) + version: 14.2.0(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1)) knip: specifier: ^5.69.1 - version: 5.82.1(@types/node@25.0.9)(typescript@5.9.3) + version: 5.83.0(@types/node@25.2.0)(typescript@5.9.3) react: specifier: ^18.3.1 version: 18.3.1 react-native: specifier: 0.77.1 - version: 0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1) + version: 0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1) react-native-webview: specifier: ^13.15.0 - version: 13.16.0(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) + version: 13.16.0(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) size-limit: specifier: ^11.2.0 version: 11.2.0 @@ -79,20 +82,20 @@ packages: '@babel/code-frame@7.10.4': resolution: {integrity: sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==} - '@babel/code-frame@7.28.6': - resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.6': - resolution: {integrity: sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==} + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.6': - resolution: {integrity: sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==} + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.6': - resolution: {integrity: sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==} + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.27.3': @@ -115,8 +118,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.5': - resolution: {integrity: sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==} + '@babel/helper-define-polyfill-provider@0.6.6': + resolution: {integrity: sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -186,8 +189,8 @@ packages: resolution: {integrity: sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.6': - resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} engines: {node: '>=6.0.0'} hasBin: true @@ -311,8 +314,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.28.6': - resolution: {integrity: sha512-9knsChgsMzBV5Yh3kkhrZNxH3oCYAfMBkNNaVN4cP2RVlFPe8wYdwwcnOsAbkdDoV9UjFtOXWrWB52M8W4jNeA==} + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -389,8 +392,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': - resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==} + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -467,14 +470,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.28.6': - resolution: {integrity: sha512-eZhoEZHYQLL5uc1gS5e9/oTknS0sSSAtd5TkKMUp3J+S/CaUjagc0kOUPsEbDmMeva0nC3WWl4SxVY6+OBuxfw==} + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-runtime@7.28.5': - resolution: {integrity: sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==} + '@babel/plugin-transform-runtime@7.29.0': + resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -535,67 +538,67 @@ packages: resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.6': - resolution: {integrity: sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==} + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.6': - resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} - '@biomejs/biome@2.3.11': - resolution: {integrity: sha512-/zt+6qazBWguPG6+eWmiELqO+9jRsMZ/DBU3lfuU2ngtIQYzymocHhKiZRyrbra4aCOoyTg/BmY+6WH5mv9xmQ==} + '@biomejs/biome@2.3.14': + resolution: {integrity: sha512-QMT6QviX0WqXJCaiqVMiBUCr5WRQ1iFSjvOLoTk6auKukJMvnMzWucXpwZB0e8F00/1/BsS9DzcKgWH+CLqVuA==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.3.11': - resolution: {integrity: sha512-/uXXkBcPKVQY7rc9Ys2CrlirBJYbpESEDme7RKiBD6MmqR2w3j0+ZZXRIL2xiaNPsIMMNhP1YnA+jRRxoOAFrA==} + '@biomejs/cli-darwin-arm64@2.3.14': + resolution: {integrity: sha512-UJGPpvWJMkLxSRtpCAKfKh41Q4JJXisvxZL8ChN1eNW3m/WlPFJ6EFDCE7YfUb4XS8ZFi3C1dFpxUJ0Ety5n+A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.3.11': - resolution: {integrity: sha512-fh7nnvbweDPm2xEmFjfmq7zSUiox88plgdHF9OIW4i99WnXrAC3o2P3ag9judoUMv8FCSUnlwJCM1B64nO5Fbg==} + '@biomejs/cli-darwin-x64@2.3.14': + resolution: {integrity: sha512-PNkLNQG6RLo8lG7QoWe/hhnMxJIt1tEimoXpGQjwS/dkdNiKBLPv4RpeQl8o3s1OKI3ZOR5XPiYtmbGGHAOnLA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.3.11': - resolution: {integrity: sha512-XPSQ+XIPZMLaZ6zveQdwNjbX+QdROEd1zPgMwD47zvHV+tCGB88VH+aynyGxAHdzL+Tm/+DtKST5SECs4iwCLg==} + '@biomejs/cli-linux-arm64-musl@2.3.14': + resolution: {integrity: sha512-LInRbXhYujtL3sH2TMCH/UBwJZsoGwfQjBrMfl84CD4hL/41C/EU5mldqf1yoFpsI0iPWuU83U+nB2TUUypWeg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [musl] - '@biomejs/cli-linux-arm64@2.3.11': - resolution: {integrity: sha512-l4xkGa9E7Uc0/05qU2lMYfN1H+fzzkHgaJoy98wO+b/7Gl78srbCRRgwYSW+BTLixTBrM6Ede5NSBwt7rd/i6g==} + '@biomejs/cli-linux-arm64@2.3.14': + resolution: {integrity: sha512-KT67FKfzIw6DNnUNdYlBg+eU24Go3n75GWK6NwU4+yJmDYFe9i/MjiI+U/iEzKvo0g7G7MZqoyrhIYuND2w8QQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [glibc] - '@biomejs/cli-linux-x64-musl@2.3.11': - resolution: {integrity: sha512-vU7a8wLs5C9yJ4CB8a44r12aXYb8yYgBn+WeyzbMjaCMklzCv1oXr8x+VEyWodgJt9bDmhiaW/I0RHbn7rsNmw==} + '@biomejs/cli-linux-x64-musl@2.3.14': + resolution: {integrity: sha512-KQU7EkbBBuHPW3/rAcoiVmhlPtDSGOGRPv9js7qJVpYTzjQmVR+C9Rfcz+ti8YCH+zT1J52tuBybtP4IodjxZQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [musl] - '@biomejs/cli-linux-x64@2.3.11': - resolution: {integrity: sha512-/1s9V/H3cSe0r0Mv/Z8JryF5x9ywRxywomqZVLHAoa/uN0eY7F8gEngWKNS5vbbN/BsfpCG5yeBT5ENh50Frxg==} + '@biomejs/cli-linux-x64@2.3.14': + resolution: {integrity: sha512-ZsZzQsl9U+wxFrGGS4f6UxREUlgHwmEfu1IrXlgNFrNnd5Th6lIJr8KmSzu/+meSa9f4rzFrbEW9LBBA6ScoMA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [glibc] - '@biomejs/cli-win32-arm64@2.3.11': - resolution: {integrity: sha512-PZQ6ElCOnkYapSsysiTy0+fYX+agXPlWugh6+eQ6uPKI3vKAqNp6TnMhoM3oY2NltSB89hz59o8xIfOdyhi9Iw==} + '@biomejs/cli-win32-arm64@2.3.14': + resolution: {integrity: sha512-+IKYkj/pUBbnRf1G1+RlyA3LWiDgra1xpS7H2g4BuOzzRbRB+hmlw0yFsLprHhbbt7jUzbzAbAjK/Pn0FDnh1A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.3.11': - resolution: {integrity: sha512-43VrG813EW+b5+YbDbz31uUsheX+qFKCpXeY9kfdAx+ww3naKxeVkTD9zLIWxUPfJquANMHrmW3wbe/037G0Qg==} + '@biomejs/cli-win32-x64@2.3.14': + resolution: {integrity: sha512-oizCjdyQ3WJEswpb3Chdngeat56rIdSYK12JI3iI11Mt5T5EXcZ7WLuowzEaFPNJ3zmOQFliMN8QY1Pi+qsfdQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -913,8 +916,8 @@ packages: '@expo/sdk-runtime-versions@1.0.0': resolution: {integrity: sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==} - '@gerrit0/mini-shiki@3.21.0': - resolution: {integrity: sha512-9PrsT5DjZA+w3lur/aOIx3FlDeHdyCEFlv9U+fmsVyjPZh61G5SYURQ/1ebe2U63KbDmI2V8IhIUegWb8hjOyg==} + '@gerrit0/mini-shiki@3.22.0': + resolution: {integrity: sha512-jMpciqEVUBKE1QwU64S4saNMzpsSza6diNCk4MWAeCxO2+LFi2FIFmL2S0VDLzEJCxuvCbU783xi8Hp/gkM5CQ==} '@inquirer/external-editor@1.0.3': resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} @@ -929,8 +932,8 @@ packages: resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + '@isaacs/brace-expansion@5.0.1': + resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} engines: {node: 20 || >=22} '@isaacs/ttlcache@1.4.1': @@ -1009,117 +1012,117 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@openfort/openfort-js@1.1.4': - resolution: {integrity: sha512-sJQ/QBchkAgYNIkRkYHMRm7wx5QohkBAlKM5zJRXJSHqkDUhSz57XIVCapq8Jkw7UBbIbqwwVYxLqi8FlEKJfg==} + '@openfort/openfort-js@1.1.5': + resolution: {integrity: sha512-Cx1f/H+/QSL12+deiv9piScSsjM8qVShMr33AdipdoEieKhW3ADpXiZrvKWKFfL5O2PWBN5Tcz7oWwpHEwSCbg==} '@openfort/shield-js@0.1.34': resolution: {integrity: sha512-bJxQc0zk0VPxk7CWSE5NZp5Bv8nYnStwG5GKXrS2A6hxEt0vf4BMu9db4IUiHxmgGaFWrdAnbSCSZ5AU1gwyew==} - '@oxc-resolver/binding-android-arm-eabi@11.16.3': - resolution: {integrity: sha512-CVyWHu6ACDqDcJxR4nmGiG8vDF4TISJHqRNzac5z/gPQycs/QrP/1pDsJBy0MD7jSw8nVq2E5WqeHQKabBG/Jg==} + '@oxc-resolver/binding-android-arm-eabi@11.17.0': + resolution: {integrity: sha512-kVnY21v0GyZ/+LG6EIO48wK3mE79BUuakHUYLIqobO/Qqq4mJsjuYXMSn3JtLcKZpN1HDVit4UHpGJHef1lrlw==} cpu: [arm] os: [android] - '@oxc-resolver/binding-android-arm64@11.16.3': - resolution: {integrity: sha512-tTIoB7plLeh2o6Ay7NnV5CJb6QUXdxI7Shnsp2ECrLSV81k+oVE3WXYrQSh4ltWL75i0OgU5Bj3bsuyg5SMepw==} + '@oxc-resolver/binding-android-arm64@11.17.0': + resolution: {integrity: sha512-Pf8e3XcsK9a8RHInoAtEcrwf2vp7V9bSturyUUYxw9syW6E7cGi7z9+6ADXxm+8KAevVfLA7pfBg8NXTvz/HOw==} cpu: [arm64] os: [android] - '@oxc-resolver/binding-darwin-arm64@11.16.3': - resolution: {integrity: sha512-OXKVH7uwYd3Rbw1s2yJZd6/w+6b01iaokZubYhDAq4tOYArr+YCS+lr81q1hsTPPRZeIsWE+rJLulmf1qHdYZA==} + '@oxc-resolver/binding-darwin-arm64@11.17.0': + resolution: {integrity: sha512-lVSgKt3biecofXVr8e1hnfX0IYMd4A6VCxmvOmHsFt5Zbmt0lkO4S2ap2bvQwYDYh5ghUNamC7M2L8K6vishhQ==} cpu: [arm64] os: [darwin] - '@oxc-resolver/binding-darwin-x64@11.16.3': - resolution: {integrity: sha512-WwjQ4WdnCxVYZYd3e3oY5XbV3JeLy9pPMK+eQQ2m8DtqUtbxnvPpAYC2Knv/2bS6q5JiktqOVJ2Hfia3OSo0/A==} + '@oxc-resolver/binding-darwin-x64@11.17.0': + resolution: {integrity: sha512-+/raxVJE1bo7R4fA9Yp0wm3slaCOofTEeUzM01YqEGcRDLHB92WRGjRhagMG2wGlvqFuSiTp81DwSbBVo/g6AQ==} cpu: [x64] os: [darwin] - '@oxc-resolver/binding-freebsd-x64@11.16.3': - resolution: {integrity: sha512-4OHKFGJBBfOnuJnelbCS4eBorI6cj54FUxcZJwEXPeoLc8yzORBoJ2w+fQbwjlQcUUZLEg92uGhKCRiUoqznjg==} + '@oxc-resolver/binding-freebsd-x64@11.17.0': + resolution: {integrity: sha512-x9Ks56n+n8h0TLhzA6sJXa2tGh3uvMGpBppg6PWf8oF0s5S/3p/J6k1vJJ9lIUtTmenfCQEGKnFokpRP4fLTLg==} cpu: [x64] os: [freebsd] - '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.3': - resolution: {integrity: sha512-OM3W0NLt9u7uKwG/yZbeXABansZC0oZeDF1nKgvcZoRw4/Yak6/l4S0onBfDFeYMY94eYeAt2bl60e30lgsb5A==} + '@oxc-resolver/binding-linux-arm-gnueabihf@11.17.0': + resolution: {integrity: sha512-Wf3w07Ow9kXVJrS0zmsaFHKOGhXKXE8j1tNyy+qIYDsQWQ4UQZVx5SjlDTcqBnFerlp3Z3Is0RjmVzgoLG3qkA==} cpu: [arm] os: [linux] - '@oxc-resolver/binding-linux-arm-musleabihf@11.16.3': - resolution: {integrity: sha512-MRs7D7i1t7ACsAdTuP81gLZES918EpBmiUyEl8fu302yQB+4L7L7z0Ui8BWnthUTQd3nAU9dXvENLK/SqRVH8A==} + '@oxc-resolver/binding-linux-arm-musleabihf@11.17.0': + resolution: {integrity: sha512-N0OKA1al1gQ5Gm7Fui1RWlXaHRNZlwMoBLn3TVtSXX+WbnlZoVyDqqOqFL8+pVEHhhxEA2LR8kmM0JO6FAk6dg==} cpu: [arm] os: [linux] - '@oxc-resolver/binding-linux-arm64-gnu@11.16.3': - resolution: {integrity: sha512-0eVYZxSceNqGADzhlV4ZRqkHF0fjWxRXQOB7Qwl5y1gN/XYUDvMfip+ngtzj4dM7zQT4U97hUhJ7PUKSy/JIGQ==} + '@oxc-resolver/binding-linux-arm64-gnu@11.17.0': + resolution: {integrity: sha512-wdcQ7Niad9JpjZIGEeqKJnTvczVunqlZ/C06QzR5zOQNeLVRScQ9S5IesKWUAPsJQDizV+teQX53nTK+Z5Iy+g==} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-resolver/binding-linux-arm64-musl@11.16.3': - resolution: {integrity: sha512-B1BvLeZbgDdVN0FvU40l5Q7lej8310WlabCBaouk8jY7H7xbI8phtomTtk3Efmevgfy5hImaQJu6++OmcFb2NQ==} + '@oxc-resolver/binding-linux-arm64-musl@11.17.0': + resolution: {integrity: sha512-65B2/t39HQN5AEhkLsC+9yBD1iRUkKOIhfmJEJ7g6wQ9kylra7JRmNmALFjbsj0VJsoSQkpM8K07kUZuNJ9Kxw==} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-resolver/binding-linux-ppc64-gnu@11.16.3': - resolution: {integrity: sha512-q7khglic3Jqak7uDgA3MFnjDeI7krQT595GDZpvFq785fmFYSx8rlTkoHzmhQtUisYtl4XG7WUscwsoidFUI4w==} + '@oxc-resolver/binding-linux-ppc64-gnu@11.17.0': + resolution: {integrity: sha512-kExgm3TLK21dNMmcH+xiYGbc6BUWvT03PUZ2aYn8mUzGPeeORklBhg3iYcaBI3ZQHB25412X1Z6LLYNjt4aIaA==} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-resolver/binding-linux-riscv64-gnu@11.16.3': - resolution: {integrity: sha512-aFRNmQNPzDgQEbw2s3c8yJYRimacSDI+u9df8rn5nSKzTVitHmbEpZqfxpwNLCKIuLSNmozHR1z1OT+oZVeYqg==} + '@oxc-resolver/binding-linux-riscv64-gnu@11.17.0': + resolution: {integrity: sha512-1utUJC714/ydykZQE8c7QhpEyM4SaslMfRXxN9G61KYazr6ndt85LaubK3EZCSD50vVEfF4PVwFysCSO7LN9uA==} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-resolver/binding-linux-riscv64-musl@11.16.3': - resolution: {integrity: sha512-vZI85SvSMADcEL9G1TIrV0Rlkc1fY5Mup0DdlVC5EHPysZB4hXXHpr+h09pjlK5y+5om5foIzDRxE1baUCaWOA==} + '@oxc-resolver/binding-linux-riscv64-musl@11.17.0': + resolution: {integrity: sha512-mayiYOl3LMmtO2CLn4I5lhanfxEo0LAqlT/EQyFbu1ZN3RS+Xa7Q3JEM0wBpVIyfO/pqFrjvC5LXw/mHNDEL7A==} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-resolver/binding-linux-s390x-gnu@11.16.3': - resolution: {integrity: sha512-xiLBnaUlddFEzRHiHiSGEMbkg8EwZY6VD8F+3GfnFsiK3xg/4boaUV2bwXd+nUzl3UDQOMW1QcZJ4jJSb0qiJA==} + '@oxc-resolver/binding-linux-s390x-gnu@11.17.0': + resolution: {integrity: sha512-Ow/yI+CrUHxIIhn/Y1sP/xoRKbCC3x9O1giKr3G/pjMe+TCJ5ZmfqVWU61JWwh1naC8X5Xa7uyLnbzyYqPsHfg==} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-resolver/binding-linux-x64-gnu@11.16.3': - resolution: {integrity: sha512-6y0b05wIazJJgwu7yU/AYGFswzQQudYJBOb/otDhiDacp1+6ye8egoxx63iVo9lSpDbipL++54AJQFlcOHCB+g==} + '@oxc-resolver/binding-linux-x64-gnu@11.17.0': + resolution: {integrity: sha512-Z4J7XlPMQOLPANyu6y3B3V417Md4LKH5bV6bhqgaG99qLHmU5LV2k9ErV14fSqoRc/GU/qOpqMdotxiJqN/YWg==} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-resolver/binding-linux-x64-musl@11.16.3': - resolution: {integrity: sha512-RmMgwuMa42c9logS7Pjprf5KCp8J1a1bFiuBFtG9/+yMu0BhY2t+0VR/um7pwtkNFvIQqAVh6gDOg/PnoKRcdQ==} + '@oxc-resolver/binding-linux-x64-musl@11.17.0': + resolution: {integrity: sha512-0effK+8lhzXsgsh0Ny2ngdnTPF30v6QQzVFApJ1Ctk315YgpGkghkelvrLYYgtgeFJFrzwmOJ2nDvCrUFKsS2Q==} cpu: [x64] os: [linux] libc: [musl] - '@oxc-resolver/binding-openharmony-arm64@11.16.3': - resolution: {integrity: sha512-/7AYRkjjW7xu1nrHgWUFy99Duj4/ydOBVaHtODie9/M6fFngo+8uQDFFnzmr4q//sd/cchIerISp/8CQ5TsqIA==} + '@oxc-resolver/binding-openharmony-arm64@11.17.0': + resolution: {integrity: sha512-kFB48dRUW6RovAICZaxHKdtZe+e94fSTNA2OedXokzMctoU54NPZcv0vUX5PMqyikLIKJBIlW7laQidnAzNrDA==} cpu: [arm64] os: [openharmony] - '@oxc-resolver/binding-wasm32-wasi@11.16.3': - resolution: {integrity: sha512-urM6aIPbi5di4BSlnpd/TWtDJgG6RD06HvLBuNM+qOYuFtY1/xPbzQ2LanBI2ycpqIoIZwsChyplALwAMdyfCQ==} + '@oxc-resolver/binding-wasm32-wasi@11.17.0': + resolution: {integrity: sha512-a3elKSBLPT0OoRPxTkCIIc+4xnOELolEBkPyvdj01a6PSdSmyJ1NExWjWLaXnT6wBMblvKde5RmSwEi3j+jZpg==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@oxc-resolver/binding-win32-arm64-msvc@11.16.3': - resolution: {integrity: sha512-QuvLqGKf7frxWHQ5TnrcY0C/hJpANsaez99Q4dAk1hen7lDTD4FBPtBzPnntLFXeaVG3PnSmnVjlv0vMILwU7Q==} + '@oxc-resolver/binding-win32-arm64-msvc@11.17.0': + resolution: {integrity: sha512-4eszUsSDb9YVx0RtYkPWkxxtSZIOgfeiX//nG5cwRRArg178w4RCqEF1kbKPud9HPrp1rXh7gE4x911OhvTnPg==} cpu: [arm64] os: [win32] - '@oxc-resolver/binding-win32-ia32-msvc@11.16.3': - resolution: {integrity: sha512-QR/witXK6BmYTlEP8CCjC5fxeG5U9A6a50pNpC1nLnhAcJjtzFG8KcQ5etVy/XvCLiDc7fReaAWRNWtCaIhM8Q==} + '@oxc-resolver/binding-win32-ia32-msvc@11.17.0': + resolution: {integrity: sha512-t946xTXMmR7yGH0KAe9rB055/X4EPIu93JUvjchl2cizR5QbuwkUV7vLS2BS6x6sfvDoQb6rWYnV1HCci6tBSg==} cpu: [ia32] os: [win32] - '@oxc-resolver/binding-win32-x64-msvc@11.16.3': - resolution: {integrity: sha512-bFuJRKOscsDAEZ/a8BezcTMAe2BQ/OBRfuMLFUuINfTR5qGVcm4a3xBIrQVepBaPxFj16SJdRjGe05vDiwZmFw==} + '@oxc-resolver/binding-win32-x64-msvc@11.17.0': + resolution: {integrity: sha512-pX6s2kMXLQg+hlqKk5UqOW09iLLxnTkvn8ohpYp2Mhsm2yzDPCx9dyOHiB/CQixLzTkLQgWWJykN4Z3UfRKW4Q==} cpu: [x64] os: [win32] @@ -1208,23 +1211,23 @@ packages: resolution: {integrity: sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==} engines: {node: '>=18'} - '@shikijs/engine-oniguruma@3.21.0': - resolution: {integrity: sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==} + '@shikijs/engine-oniguruma@3.22.0': + resolution: {integrity: sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==} - '@shikijs/langs@3.21.0': - resolution: {integrity: sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==} + '@shikijs/langs@3.22.0': + resolution: {integrity: sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==} - '@shikijs/themes@3.21.0': - resolution: {integrity: sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==} + '@shikijs/themes@3.22.0': + resolution: {integrity: sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==} - '@shikijs/types@3.21.0': - resolution: {integrity: sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==} + '@shikijs/types@3.22.0': + resolution: {integrity: sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==} '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sinclair/typebox@0.27.10': + resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} @@ -1285,8 +1288,8 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@25.0.9': - resolution: {integrity: sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==} + '@types/node@25.2.0': + resolution: {integrity: sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==} '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} @@ -1384,8 +1387,8 @@ packages: axios@1.12.2: resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} - axios@1.13.2: - resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + axios@1.13.4: + resolution: {integrity: sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==} babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} @@ -1401,8 +1404,8 @@ packages: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - babel-plugin-polyfill-corejs2@0.4.14: - resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} + babel-plugin-polyfill-corejs2@0.4.15: + resolution: {integrity: sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -1411,8 +1414,8 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.5: - resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==} + babel-plugin-polyfill-regenerator@0.6.6: + resolution: {integrity: sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -1439,8 +1442,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.9.16: - resolution: {integrity: sha512-KeUZdBuxngy825i8xvzaK1Ncnkx0tBmb3k8DkEuqjKRkmtvNTjey2ZsNeh8Dw4lfKvbCOu9oeNx2TKm2vHqcRw==} + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} hasBin: true bech32@1.1.4: @@ -1522,8 +1525,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001765: - resolution: {integrity: sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==} + caniuse-lite@1.0.30001767: + resolution: {integrity: sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -1604,8 +1607,8 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - core-js-compat@3.47.0: - resolution: {integrity: sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==} + core-js-compat@3.48.0: + resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} cosmiconfig@5.2.1: resolution: {integrity: sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==} @@ -1681,8 +1684,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.267: - resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + electron-to-chromium@1.5.286: + resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} elliptic@6.6.1: resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} @@ -1861,8 +1864,8 @@ packages: flow-enums-runtime@0.0.6: resolution: {integrity: sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==} - flow-parser@0.297.0: - resolution: {integrity: sha512-51kjVLwebsDNCrBrm+VLBJ1rEZffrWzsEPjfbdhf/0lxQkX01zFoiojwEW7l6902p1ZQI/ju/QmLGowwne23lg==} + flow-parser@0.299.0: + resolution: {integrity: sha512-phGMRoNt6SNglPHGRbCyWm9/pxfe6t/t4++EIYPaBGWT6e0lphLBgUMrvpL62NbRo9R549o3oqrbKHq82kANCw==} engines: {node: '>=0.4.0'} follow-redirects@1.15.11: @@ -1934,13 +1937,13 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - glob@13.0.0: - resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} + glob@13.0.1: + resolution: {integrity: sha512-B7U/vJpE3DkJ5WXTgTpTRN63uV42DseiXXKMwG14LQBXmsdeIoHAPbU/MEo6II0k5ED74uc2ZGTC6MwHFQhF6w==} engines: {node: 20 || >=22} glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} @@ -2184,8 +2187,8 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - knip@5.82.1: - resolution: {integrity: sha512-1nQk+5AcnkqL40kGQXfouzAEXkTR+eSrgo/8m1d0BMei4eAzFwghoXC4gOKbACgBiCof7hE8wkBVDsEvznf85w==} + knip@5.83.0: + resolution: {integrity: sha512-FfmaHMntpZB13B1oJQMSs1hTOZxd0TOn+FYB3oWEI02XlxTW3RH4H7d8z5Us3g0ziHCYyl7z0B1xi8ENP3QEKA==} engines: {node: '>=18.18.0'} hasBin: true peerDependencies: @@ -2230,8 +2233,8 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - lru-cache@11.2.4: - resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} + lru-cache@11.2.5: + resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -2352,8 +2355,8 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + minimatch@10.1.2: + resolution: {integrity: sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==} engines: {node: 20 || >=22} minimatch@3.1.2: @@ -2455,8 +2458,8 @@ packages: outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - oxc-resolver@11.16.3: - resolution: {integrity: sha512-goLOJH3x69VouGWGp5CgCIHyksmOZzXr36lsRmQz1APg3SPFORrvV2q7nsUHMzLVa6ZJgNwkgUSJFsbCpAWkCA==} + oxc-resolver@11.17.0: + resolution: {integrity: sha512-R5P2Tw6th+nQJdNcZGfuppBS/sM0x1EukqYffmlfX2xXLgLGCCPwu4ruEr9Sx29mrpkHgITc130Qps2JR90NdQ==} p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} @@ -2585,6 +2588,13 @@ packages: react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-native-passkeys@0.4.0: + resolution: {integrity: sha512-WX0jw60tDyZ3SwhnKvAdddwC27efT4CWWcq/j8O+RyGU/wIidQXeaAtX0kX1CMGNsXnoDDgbMAhUbIG+Ia786Q==} + peerDependencies: + expo: '>=48.0.0' + react: '*' + react-native: '>=0.71.0' + react-native-webview@13.16.0: resolution: {integrity: sha512-Nh13xKZWW35C0dbOskD7OX01nQQavOzHbCw9XoZmar4eXCo7AvrYJ0jlUfRVVIJzqINxHlpECYLdmAdFsl9xDA==} peerDependencies: @@ -3072,8 +3082,8 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - zod@4.3.5: - resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} snapshots: @@ -3081,25 +3091,25 @@ snapshots: dependencies: '@babel/highlight': 7.25.9 - '@babel/code-frame@7.28.6': + '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.6': {} + '@babel/compat-data@7.29.0': {} - '@babel/core@7.28.6': + '@babel/core@7.29.0': dependencies: - '@babel/code-frame': 7.28.6 - '@babel/generator': 7.28.6 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) '@babel/helpers': 7.28.6 - '@babel/parser': 7.28.6 + '@babel/parser': 7.29.0 '@babel/template': 7.28.6 - '@babel/traverse': 7.28.6 - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3 @@ -3109,49 +3119,49 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.28.6': + '@babel/generator@7.29.1': dependencies: - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@babel/helper-compilation-targets@7.28.6': dependencies: - '@babel/compat-data': 7.28.6 + '@babel/compat-data': 7.29.0 '@babel/helper-validator-option': 7.27.1 browserslist: 4.28.1 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.28.6)': + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.28.6) + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.6 + '@babel/traverse': 7.29.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.28.6)': + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.6)': + '@babel/helper-define-polyfill-provider@0.6.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 debug: 4.4.3 @@ -3164,55 +3174,55 @@ snapshots: '@babel/helper-member-expression-to-functions@7.28.5': dependencies: - '@babel/traverse': 7.28.6 - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.28.6': dependencies: - '@babel/traverse': 7.28.6 - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.6)': + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@babel/helper-plugin-utils@7.28.6': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.6)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-wrap-function': 7.28.6 - '@babel/traverse': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.28.6(@babel/core@7.28.6)': + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.6 - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -3225,15 +3235,15 @@ snapshots: '@babel/helper-wrap-function@7.28.6': dependencies: '@babel/template': 7.28.6 - '@babel/traverse': 7.28.6 - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helpers@7.28.6': dependencies: '@babel/template': 7.28.6 - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@babel/highlight@7.25.9': dependencies: @@ -3242,379 +3252,379 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/parser@7.28.6': + '@babel/parser@7.29.0': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 - '@babel/plugin-proposal-export-default-from@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-proposal-export-default-from@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.6)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.6)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.6)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.6)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.28.6)': + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-export-default-from@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-syntax-export-default-from@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-flow@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.6)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.6)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.6)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.6)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.6)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.6)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.6)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.6)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.6)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.6)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-async-generator-functions@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.6) - '@babel/traverse': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.6) + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.6) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-globals': 7.28.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.28.6) - '@babel/traverse': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/template': 7.28.6 - '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.6)': + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.28.6) + '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.6) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.6) - '@babel/traverse': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.6)': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.6) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.6) + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.6)': + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-module-imports': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.28.6) - '@babel/types': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-regenerator@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-runtime@7.28.5(@babel/core@7.28.6)': + '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.6) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.6) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.6) + babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-spread@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.6) + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.28.6) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.6)': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/preset-flow@7.27.1(@babel/core@7.28.6)': + '@babel/preset-flow@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.28.6) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.29.0) - '@babel/preset-typescript@7.28.5(@babel/core@7.28.6)': + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.28.6) + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/register@7.28.6(@babel/core@7.28.6)': + '@babel/register@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 clone-deep: 4.0.1 find-cache-dir: 2.1.0 make-dir: 2.1.0 @@ -3625,60 +3635,60 @@ snapshots: '@babel/template@7.28.6': dependencies: - '@babel/code-frame': 7.28.6 - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 - '@babel/traverse@7.28.6': + '@babel/traverse@7.29.0': dependencies: - '@babel/code-frame': 7.28.6 - '@babel/generator': 7.28.6 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.6 + '@babel/parser': 7.29.0 '@babel/template': 7.28.6 - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.6': + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@biomejs/biome@2.3.11': + '@biomejs/biome@2.3.14': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.3.11 - '@biomejs/cli-darwin-x64': 2.3.11 - '@biomejs/cli-linux-arm64': 2.3.11 - '@biomejs/cli-linux-arm64-musl': 2.3.11 - '@biomejs/cli-linux-x64': 2.3.11 - '@biomejs/cli-linux-x64-musl': 2.3.11 - '@biomejs/cli-win32-arm64': 2.3.11 - '@biomejs/cli-win32-x64': 2.3.11 - - '@biomejs/cli-darwin-arm64@2.3.11': + '@biomejs/cli-darwin-arm64': 2.3.14 + '@biomejs/cli-darwin-x64': 2.3.14 + '@biomejs/cli-linux-arm64': 2.3.14 + '@biomejs/cli-linux-arm64-musl': 2.3.14 + '@biomejs/cli-linux-x64': 2.3.14 + '@biomejs/cli-linux-x64-musl': 2.3.14 + '@biomejs/cli-win32-arm64': 2.3.14 + '@biomejs/cli-win32-x64': 2.3.14 + + '@biomejs/cli-darwin-arm64@2.3.14': optional: true - '@biomejs/cli-darwin-x64@2.3.11': + '@biomejs/cli-darwin-x64@2.3.14': optional: true - '@biomejs/cli-linux-arm64-musl@2.3.11': + '@biomejs/cli-linux-arm64-musl@2.3.14': optional: true - '@biomejs/cli-linux-arm64@2.3.11': + '@biomejs/cli-linux-arm64@2.3.14': optional: true - '@biomejs/cli-linux-x64-musl@2.3.11': + '@biomejs/cli-linux-x64-musl@2.3.14': optional: true - '@biomejs/cli-linux-x64@2.3.11': + '@biomejs/cli-linux-x64@2.3.14': optional: true - '@biomejs/cli-win32-arm64@2.3.11': + '@biomejs/cli-win32-arm64@2.3.14': optional: true - '@biomejs/cli-win32-x64@2.3.11': + '@biomejs/cli-win32-x64@2.3.14': optional: true '@changesets/apply-release-plan@7.0.14': @@ -3718,7 +3728,7 @@ snapshots: transitivePeerDependencies: - encoding - '@changesets/cli@2.29.8(@types/node@25.0.9)': + '@changesets/cli@2.29.8(@types/node@25.2.0)': dependencies: '@changesets/apply-release-plan': 7.0.14 '@changesets/assemble-release-plan': 6.0.9 @@ -3734,7 +3744,7 @@ snapshots: '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@25.0.9) + '@inquirer/external-editor': 1.0.3(@types/node@25.2.0) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 ci-info: 3.9.0 @@ -4108,7 +4118,7 @@ snapshots: chalk: 4.1.2 debug: 4.4.3 getenv: 2.0.0 - glob: 13.0.0 + glob: 13.0.1 resolve-from: 5.0.0 semver: 7.7.3 slash: 3.0.0 @@ -4128,7 +4138,7 @@ snapshots: '@expo/json-file': 9.1.5 deepmerge: 4.3.1 getenv: 2.0.0 - glob: 13.0.0 + glob: 13.0.1 require-from-string: 2.0.2 resolve-from: 5.0.0 resolve-workspace-root: 2.0.1 @@ -4161,24 +4171,24 @@ snapshots: '@expo/sdk-runtime-versions@1.0.0': {} - '@gerrit0/mini-shiki@3.21.0': + '@gerrit0/mini-shiki@3.22.0': dependencies: - '@shikijs/engine-oniguruma': 3.21.0 - '@shikijs/langs': 3.21.0 - '@shikijs/themes': 3.21.0 - '@shikijs/types': 3.21.0 + '@shikijs/engine-oniguruma': 3.22.0 + '@shikijs/langs': 3.22.0 + '@shikijs/themes': 3.22.0 + '@shikijs/types': 3.22.0 '@shikijs/vscode-textmate': 10.0.2 - '@inquirer/external-editor@1.0.3(@types/node@25.0.9)': + '@inquirer/external-editor@1.0.3(@types/node@25.2.0)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 25.0.9 + '@types/node': 25.2.0 '@isaacs/balanced-match@4.0.1': {} - '@isaacs/brace-expansion@5.0.0': + '@isaacs/brace-expansion@5.0.1': dependencies: '@isaacs/balanced-match': 4.0.1 @@ -4202,25 +4212,25 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.0.9 + '@types/node': 25.2.0 jest-mock: 29.7.0 '@jest/fake-timers@29.7.0': dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 25.0.9 + '@types/node': 25.2.0 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 '@jest/schemas@29.6.3': dependencies: - '@sinclair/typebox': 0.27.8 + '@sinclair/typebox': 0.27.10 '@jest/transform@29.7.0': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.31 babel-plugin-istanbul: 6.1.1 @@ -4243,7 +4253,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 25.0.9 + '@types/node': 25.2.0 '@types/yargs': 17.0.35 chalk: 4.1.2 @@ -4306,7 +4316,7 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@openfort/openfort-js@1.1.4': + '@openfort/openfort-js@1.1.5': dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -4317,8 +4327,8 @@ snapshots: '@openfort/shield-js': 0.1.34 '@sentry/browser': 9.47.1 '@sentry/core': 9.47.1 - axios: 1.13.2 - axios-retry: 4.5.0(axios@1.13.2) + axios: 1.13.4 + axios-retry: 4.5.0(axios@1.13.4) eventemitter3: 5.0.1 human-id: 4.1.3 transitivePeerDependencies: @@ -4333,73 +4343,73 @@ snapshots: transitivePeerDependencies: - debug - '@oxc-resolver/binding-android-arm-eabi@11.16.3': + '@oxc-resolver/binding-android-arm-eabi@11.17.0': optional: true - '@oxc-resolver/binding-android-arm64@11.16.3': + '@oxc-resolver/binding-android-arm64@11.17.0': optional: true - '@oxc-resolver/binding-darwin-arm64@11.16.3': + '@oxc-resolver/binding-darwin-arm64@11.17.0': optional: true - '@oxc-resolver/binding-darwin-x64@11.16.3': + '@oxc-resolver/binding-darwin-x64@11.17.0': optional: true - '@oxc-resolver/binding-freebsd-x64@11.16.3': + '@oxc-resolver/binding-freebsd-x64@11.17.0': optional: true - '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.3': + '@oxc-resolver/binding-linux-arm-gnueabihf@11.17.0': optional: true - '@oxc-resolver/binding-linux-arm-musleabihf@11.16.3': + '@oxc-resolver/binding-linux-arm-musleabihf@11.17.0': optional: true - '@oxc-resolver/binding-linux-arm64-gnu@11.16.3': + '@oxc-resolver/binding-linux-arm64-gnu@11.17.0': optional: true - '@oxc-resolver/binding-linux-arm64-musl@11.16.3': + '@oxc-resolver/binding-linux-arm64-musl@11.17.0': optional: true - '@oxc-resolver/binding-linux-ppc64-gnu@11.16.3': + '@oxc-resolver/binding-linux-ppc64-gnu@11.17.0': optional: true - '@oxc-resolver/binding-linux-riscv64-gnu@11.16.3': + '@oxc-resolver/binding-linux-riscv64-gnu@11.17.0': optional: true - '@oxc-resolver/binding-linux-riscv64-musl@11.16.3': + '@oxc-resolver/binding-linux-riscv64-musl@11.17.0': optional: true - '@oxc-resolver/binding-linux-s390x-gnu@11.16.3': + '@oxc-resolver/binding-linux-s390x-gnu@11.17.0': optional: true - '@oxc-resolver/binding-linux-x64-gnu@11.16.3': + '@oxc-resolver/binding-linux-x64-gnu@11.17.0': optional: true - '@oxc-resolver/binding-linux-x64-musl@11.16.3': + '@oxc-resolver/binding-linux-x64-musl@11.17.0': optional: true - '@oxc-resolver/binding-openharmony-arm64@11.16.3': + '@oxc-resolver/binding-openharmony-arm64@11.17.0': optional: true - '@oxc-resolver/binding-wasm32-wasi@11.16.3': + '@oxc-resolver/binding-wasm32-wasi@11.17.0': dependencies: '@napi-rs/wasm-runtime': 1.1.1 optional: true - '@oxc-resolver/binding-win32-arm64-msvc@11.16.3': + '@oxc-resolver/binding-win32-arm64-msvc@11.17.0': optional: true - '@oxc-resolver/binding-win32-ia32-msvc@11.16.3': + '@oxc-resolver/binding-win32-ia32-msvc@11.17.0': optional: true - '@oxc-resolver/binding-win32-x64-msvc@11.16.3': + '@oxc-resolver/binding-win32-x64-msvc@11.17.0': optional: true '@react-native/assets-registry@0.77.1': {} '@react-native/babel-plugin-codegen@0.77.1': dependencies: - '@babel/traverse': 7.28.6 + '@babel/traverse': 7.29.0 '@react-native/codegen': 0.77.1 transitivePeerDependencies: - '@babel/preset-env' @@ -4407,50 +4417,50 @@ snapshots: '@react-native/babel-preset@0.77.1': dependencies: - '@babel/core': 7.28.6 - '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.28.6) - '@babel/plugin-syntax-export-default-from': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.6) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.6) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-async-generator-functions': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.6) - '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.6) - '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.6) - '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-regenerator': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-runtime': 7.28.5(@babel/core@7.28.6) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.6) + '@babel/core': 7.29.0 + '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-export-default-from': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) '@babel/template': 7.28.6 '@react-native/babel-plugin-codegen': 0.77.1 babel-plugin-syntax-hermes-parser: 0.25.1 - babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.28.6) + babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.29.0) react-refresh: 0.14.2 transitivePeerDependencies: - '@babel/preset-env' @@ -4458,7 +4468,7 @@ snapshots: '@react-native/codegen@0.77.1': dependencies: - '@babel/parser': 7.28.6 + '@babel/parser': 7.29.0 glob: 7.2.3 hermes-parser: 0.25.1 invariant: 2.2.4 @@ -4513,7 +4523,7 @@ snapshots: '@react-native/metro-babel-transformer@0.77.1': dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@react-native/babel-preset': 0.77.1 hermes-parser: 0.25.1 nullthrows: 1.1.1 @@ -4523,12 +4533,12 @@ snapshots: '@react-native/normalize-colors@0.77.1': {} - '@react-native/virtualized-lists@0.77.1(@types/react@18.3.27)(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)': + '@react-native/virtualized-lists@0.77.1(@types/react@18.3.27)(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)': dependencies: invariant: 2.2.4 nullthrows: 1.1.1 react: 18.3.1 - react-native: 0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1) + react-native: 0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1) optionalDependencies: '@types/react': 18.3.27 @@ -4560,27 +4570,27 @@ snapshots: '@sentry/core@9.47.1': {} - '@shikijs/engine-oniguruma@3.21.0': + '@shikijs/engine-oniguruma@3.22.0': dependencies: - '@shikijs/types': 3.21.0 + '@shikijs/types': 3.22.0 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/langs@3.21.0': + '@shikijs/langs@3.22.0': dependencies: - '@shikijs/types': 3.21.0 + '@shikijs/types': 3.22.0 - '@shikijs/themes@3.21.0': + '@shikijs/themes@3.22.0': dependencies: - '@shikijs/types': 3.21.0 + '@shikijs/types': 3.22.0 - '@shikijs/types@3.21.0': + '@shikijs/types@3.22.0': dependencies: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 '@shikijs/vscode-textmate@10.0.2': {} - '@sinclair/typebox@0.27.8': {} + '@sinclair/typebox@0.27.10': {} '@sinonjs/commons@3.0.1': dependencies: @@ -4613,28 +4623,28 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 25.0.9 + '@types/node': 25.2.0 '@types/hast@3.0.4': dependencies: @@ -4652,11 +4662,11 @@ snapshots: '@types/node-forge@1.3.14': dependencies: - '@types/node': 25.0.9 + '@types/node': 25.2.0 '@types/node@12.20.55': {} - '@types/node@25.0.9': + '@types/node@25.2.0': dependencies: undici-types: 7.16.0 @@ -4736,9 +4746,9 @@ snapshots: axios: 1.12.2 is-retry-allowed: 2.2.0 - axios-retry@4.5.0(axios@1.13.2): + axios-retry@4.5.0(axios@1.13.4): dependencies: - axios: 1.13.2 + axios: 1.13.4 is-retry-allowed: 2.2.0 axios@1.12.2: @@ -4749,7 +4759,7 @@ snapshots: transitivePeerDependencies: - debug - axios@1.13.2: + axios@1.13.4: dependencies: follow-redirects: 1.15.11 form-data: 4.0.5 @@ -4757,13 +4767,13 @@ snapshots: transitivePeerDependencies: - debug - babel-jest@29.7.0(@babel/core@7.28.6): + babel-jest@29.7.0(@babel/core@7.29.0): dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 '@jest/transform': 29.7.0 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.28.6) + babel-preset-jest: 29.6.3(@babel/core@7.29.0) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -4783,31 +4793,31 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: '@babel/template': 7.28.6 - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.28.0 - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.6): + babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0): dependencies: - '@babel/compat-data': 7.28.6 - '@babel/core': 7.28.6 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.6) + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.6): + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): dependencies: - '@babel/core': 7.28.6 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.6) - core-js-compat: 3.47.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) + core-js-compat: 3.48.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.6): + babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.29.0): dependencies: - '@babel/core': 7.28.6 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.6) + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color @@ -4815,42 +4825,42 @@ snapshots: dependencies: hermes-parser: 0.25.1 - babel-plugin-transform-flow-enums@0.0.2(@babel/core@7.28.6): + babel-plugin-transform-flow-enums@0.0.2(@babel/core@7.29.0): dependencies: - '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.28.6) + '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - '@babel/core' - babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.6): - dependencies: - '@babel/core': 7.28.6 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.6) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.6) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.6) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.6) - '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.6) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.6) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.6) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.6) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.6) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.6) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.6) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.6) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.6) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.6) - - babel-preset-jest@29.6.3(@babel/core@7.28.6): - dependencies: - '@babel/core': 7.28.6 + babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.29.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0) + + babel-preset-jest@29.6.3(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.6) + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) balanced-match@1.0.2: {} base64-js@1.5.1: {} - baseline-browser-mapping@2.9.16: {} + baseline-browser-mapping@2.9.19: {} bech32@1.1.4: {} @@ -4889,9 +4899,9 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.9.16 - caniuse-lite: 1.0.30001765 - electron-to-chromium: 1.5.267 + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001767 + electron-to-chromium: 1.5.286 node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) @@ -4927,7 +4937,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001765: {} + caniuse-lite@1.0.30001767: {} chalk@2.4.2: dependencies: @@ -4948,7 +4958,7 @@ snapshots: chrome-launcher@0.15.2: dependencies: - '@types/node': 25.0.9 + '@types/node': 25.2.0 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -4957,7 +4967,7 @@ snapshots: chromium-edge-launcher@0.2.0: dependencies: - '@types/node': 25.0.9 + '@types/node': 25.2.0 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -5019,7 +5029,7 @@ snapshots: convert-source-map@2.0.0: {} - core-js-compat@3.47.0: + core-js-compat@3.48.0: dependencies: browserslist: 4.28.1 @@ -5078,7 +5088,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.267: {} + electron-to-chromium@1.5.286: {} elliptic@6.6.1: dependencies: @@ -5173,17 +5183,17 @@ snapshots: eventemitter3@5.0.1: {} - expo-apple-authentication@7.2.4(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1)): + expo-apple-authentication@7.2.4(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1)): dependencies: - react-native: 0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1) + react-native: 0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1) expo-application@6.1.5: {} - expo-constants@17.1.8(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1)): + expo-constants@17.1.8(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1)): dependencies: '@expo/config': 11.0.13 '@expo/env': 1.0.7 - react-native: 0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1) + react-native: 0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1) transitivePeerDependencies: - supports-color @@ -5191,21 +5201,21 @@ snapshots: dependencies: base64-js: 1.5.1 - expo-linking@7.1.7(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1): + expo-linking@7.1.7(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1): dependencies: - expo-constants: 17.1.8(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1)) + expo-constants: 17.1.8(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1)) invariant: 2.2.4 react: 18.3.1 - react-native: 0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1) + react-native: 0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1) transitivePeerDependencies: - expo - supports-color expo-secure-store@14.2.4: {} - expo-web-browser@14.2.0(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1)): + expo-web-browser@14.2.0(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1)): dependencies: - react-native: 0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1) + react-native: 0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1) exponential-backoff@3.1.3: {} @@ -5270,7 +5280,7 @@ snapshots: flow-enums-runtime@0.0.6: {} - flow-parser@0.297.0: {} + flow-parser@0.299.0: {} follow-redirects@1.15.11: {} @@ -5337,9 +5347,9 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@13.0.0: + glob@13.0.1: dependencies: - minimatch: 10.1.1 + minimatch: 10.1.2 minipass: 7.1.2 path-scurry: 2.0.1 @@ -5480,8 +5490,8 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.28.6 - '@babel/parser': 7.28.6 + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -5493,7 +5503,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.0.9 + '@types/node': 25.2.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -5503,7 +5513,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 25.0.9 + '@types/node': 25.2.0 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -5517,7 +5527,7 @@ snapshots: jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.28.6 + '@babel/code-frame': 7.29.0 '@jest/types': 29.6.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -5530,7 +5540,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 25.0.9 + '@types/node': 25.2.0 jest-util: 29.7.0 jest-regex-util@29.6.3: {} @@ -5538,7 +5548,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 25.0.9 + '@types/node': 25.2.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -5555,7 +5565,7 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 25.0.9 + '@types/node': 25.2.0 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -5581,17 +5591,17 @@ snapshots: jscodeshift@17.3.0: dependencies: - '@babel/core': 7.28.6 - '@babel/parser': 7.28.6 - '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.28.6) - '@babel/preset-flow': 7.27.1(@babel/core@7.28.6) - '@babel/preset-typescript': 7.28.5(@babel/core@7.28.6) - '@babel/register': 7.28.6(@babel/core@7.28.6) - flow-parser: 0.297.0 + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/preset-flow': 7.27.1(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/register': 7.28.6(@babel/core@7.29.0) + flow-parser: 0.299.0 graceful-fs: 4.2.11 micromatch: 4.0.8 neo-async: 2.6.2 @@ -5614,22 +5624,22 @@ snapshots: kind-of@6.0.3: {} - knip@5.82.1(@types/node@25.0.9)(typescript@5.9.3): + knip@5.83.0(@types/node@25.2.0)(typescript@5.9.3): dependencies: '@nodelib/fs.walk': 1.2.8 - '@types/node': 25.0.9 + '@types/node': 25.2.0 fast-glob: 3.3.3 formatly: 0.3.0 jiti: 2.6.1 js-yaml: 4.1.1 minimist: 1.2.8 - oxc-resolver: 11.16.3 + oxc-resolver: 11.17.0 picocolors: 1.1.1 picomatch: 4.0.3 smol-toml: 1.6.0 strip-json-comments: 5.0.3 typescript: 5.9.3 - zod: 4.3.5 + zod: 4.3.6 leven@3.1.0: {} @@ -5667,7 +5677,7 @@ snapshots: dependencies: js-tokens: 4.0.0 - lru-cache@11.2.4: {} + lru-cache@11.2.5: {} lru-cache@5.1.1: dependencies: @@ -5707,7 +5717,7 @@ snapshots: metro-babel-transformer@0.81.5: dependencies: - '@babel/core': 7.28.6 + '@babel/core': 7.29.0 flow-enums-runtime: 0.0.6 hermes-parser: 0.25.1 nullthrows: 1.1.1 @@ -5775,9 +5785,9 @@ snapshots: metro-source-map@0.81.5: dependencies: - '@babel/traverse': 7.28.6 - '@babel/traverse--for-generate-function-map': '@babel/traverse@7.28.6' - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/traverse--for-generate-function-map': '@babel/traverse@7.29.0' + '@babel/types': 7.29.0 flow-enums-runtime: 0.0.6 invariant: 2.2.4 metro-symbolicate: 0.81.5 @@ -5801,10 +5811,10 @@ snapshots: metro-transform-plugins@0.81.5: dependencies: - '@babel/core': 7.28.6 - '@babel/generator': 7.28.6 + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 '@babel/template': 7.28.6 - '@babel/traverse': 7.28.6 + '@babel/traverse': 7.29.0 flow-enums-runtime: 0.0.6 nullthrows: 1.1.1 transitivePeerDependencies: @@ -5812,10 +5822,10 @@ snapshots: metro-transform-worker@0.81.5: dependencies: - '@babel/core': 7.28.6 - '@babel/generator': 7.28.6 - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 flow-enums-runtime: 0.0.6 metro: 0.81.5 metro-babel-transformer: 0.81.5 @@ -5832,13 +5842,13 @@ snapshots: metro@0.81.5: dependencies: - '@babel/code-frame': 7.28.6 - '@babel/core': 7.28.6 - '@babel/generator': 7.28.6 - '@babel/parser': 7.28.6 + '@babel/code-frame': 7.29.0 + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 '@babel/template': 7.28.6 - '@babel/traverse': 7.28.6 - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 accepts: 1.3.8 chalk: 4.1.2 ci-info: 2.0.0 @@ -5894,9 +5904,9 @@ snapshots: minimalistic-crypto-utils@1.0.1: {} - minimatch@10.1.1: + minimatch@10.1.2: dependencies: - '@isaacs/brace-expansion': 5.0.0 + '@isaacs/brace-expansion': 5.0.1 minimatch@3.1.2: dependencies: @@ -5973,28 +5983,28 @@ snapshots: outdent@0.5.0: {} - oxc-resolver@11.16.3: + oxc-resolver@11.17.0: optionalDependencies: - '@oxc-resolver/binding-android-arm-eabi': 11.16.3 - '@oxc-resolver/binding-android-arm64': 11.16.3 - '@oxc-resolver/binding-darwin-arm64': 11.16.3 - '@oxc-resolver/binding-darwin-x64': 11.16.3 - '@oxc-resolver/binding-freebsd-x64': 11.16.3 - '@oxc-resolver/binding-linux-arm-gnueabihf': 11.16.3 - '@oxc-resolver/binding-linux-arm-musleabihf': 11.16.3 - '@oxc-resolver/binding-linux-arm64-gnu': 11.16.3 - '@oxc-resolver/binding-linux-arm64-musl': 11.16.3 - '@oxc-resolver/binding-linux-ppc64-gnu': 11.16.3 - '@oxc-resolver/binding-linux-riscv64-gnu': 11.16.3 - '@oxc-resolver/binding-linux-riscv64-musl': 11.16.3 - '@oxc-resolver/binding-linux-s390x-gnu': 11.16.3 - '@oxc-resolver/binding-linux-x64-gnu': 11.16.3 - '@oxc-resolver/binding-linux-x64-musl': 11.16.3 - '@oxc-resolver/binding-openharmony-arm64': 11.16.3 - '@oxc-resolver/binding-wasm32-wasi': 11.16.3 - '@oxc-resolver/binding-win32-arm64-msvc': 11.16.3 - '@oxc-resolver/binding-win32-ia32-msvc': 11.16.3 - '@oxc-resolver/binding-win32-x64-msvc': 11.16.3 + '@oxc-resolver/binding-android-arm-eabi': 11.17.0 + '@oxc-resolver/binding-android-arm64': 11.17.0 + '@oxc-resolver/binding-darwin-arm64': 11.17.0 + '@oxc-resolver/binding-darwin-x64': 11.17.0 + '@oxc-resolver/binding-freebsd-x64': 11.17.0 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.17.0 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.17.0 + '@oxc-resolver/binding-linux-arm64-gnu': 11.17.0 + '@oxc-resolver/binding-linux-arm64-musl': 11.17.0 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.17.0 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.17.0 + '@oxc-resolver/binding-linux-riscv64-musl': 11.17.0 + '@oxc-resolver/binding-linux-s390x-gnu': 11.17.0 + '@oxc-resolver/binding-linux-x64-gnu': 11.17.0 + '@oxc-resolver/binding-linux-x64-musl': 11.17.0 + '@oxc-resolver/binding-openharmony-arm64': 11.17.0 + '@oxc-resolver/binding-wasm32-wasi': 11.17.0 + '@oxc-resolver/binding-win32-arm64-msvc': 11.17.0 + '@oxc-resolver/binding-win32-ia32-msvc': 11.17.0 + '@oxc-resolver/binding-win32-x64-msvc': 11.17.0 p-filter@2.1.0: dependencies: @@ -6039,7 +6049,7 @@ snapshots: path-scurry@2.0.1: dependencies: - lru-cache: 11.2.4 + lru-cache: 11.2.5 minipass: 7.1.2 path-type@4.0.0: {} @@ -6100,14 +6110,19 @@ snapshots: react-is@18.3.1: {} - react-native-webview@13.16.0(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1): + react-native-passkeys@0.4.0(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-native: 0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1) + + react-native-webview@13.16.0(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1): dependencies: escape-string-regexp: 4.0.0 invariant: 2.2.4 react: 18.3.1 - react-native: 0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1) + react-native: 0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1) - react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1): + react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1): dependencies: '@jest/create-cache-key-function': 29.7.0 '@react-native/assets-registry': 0.77.1 @@ -6116,11 +6131,11 @@ snapshots: '@react-native/gradle-plugin': 0.77.1 '@react-native/js-polyfills': 0.77.1 '@react-native/normalize-colors': 0.77.1 - '@react-native/virtualized-lists': 0.77.1(@types/react@18.3.27)(react-native@0.77.1(@babel/core@7.28.6)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) + '@react-native/virtualized-lists': 0.77.1(@types/react@18.3.27)(react-native@0.77.1(@babel/core@7.29.0)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) abort-controller: 3.0.0 anser: 1.4.10 ansi-regex: 5.0.1 - babel-jest: 29.7.0(@babel/core@7.28.6) + babel-jest: 29.7.0(@babel/core@7.29.0) babel-plugin-syntax-hermes-parser: 0.25.1 base64-js: 1.5.1 chalk: 4.1.2 @@ -6369,7 +6384,7 @@ snapshots: dependencies: '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 - glob: 13.0.0 + glob: 13.0.1 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.7 @@ -6443,7 +6458,7 @@ snapshots: typedoc@0.28.16(typescript@5.9.3): dependencies: - '@gerrit0/mini-shiki': 3.21.0 + '@gerrit0/mini-shiki': 3.22.0 lunr: 2.3.9 markdown-it: 14.1.0 minimatch: 9.0.5 @@ -6560,4 +6575,4 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - zod@4.3.5: {} + zod@4.3.6: {} diff --git a/src/core/provider.tsx b/src/core/provider.tsx index 07f8cdc..037b923 100644 --- a/src/core/provider.tsx +++ b/src/core/provider.tsx @@ -10,7 +10,7 @@ import { import React, { useCallback, useEffect, useMemo, useState } from 'react' import { validateEnvironment } from '../lib/environmentValidation' import { getEmbeddedStateName, logger } from '../lib/logger' -import { EmbeddedWalletWebView, WebViewUtils } from '../native' +import { EmbeddedWalletWebView, NativePasskeyHandler, WebViewUtils } from '../native' import type { OAuthFlowState, PasswordFlowState, RecoveryFlowState, SiweFlowState } from '../types' import { createOpenfortClient, setDefaultClient } from './client' import { OpenfortContext, type OpenfortContextValue } from './context' @@ -24,8 +24,12 @@ export type CommonEmbeddedWalletConfiguration = { ethereumProviderPolicyId?: PolicyConfig accountType?: AccountTypeEnum debug?: boolean - /** Recovery method for the embedded wallet: 'automatic' or 'password' */ - recoveryMethod?: 'automatic' | 'password' + /** Recovery method for the embedded wallet: 'automatic', 'password', or 'passkey' */ + recoveryMethod?: 'automatic' | 'password' | 'passkey' + /** Passkey Relying Party ID (domain) for passkey-based recovery */ + passkeyRpId?: string + /** Passkey Relying Party Name for passkey-based recovery */ + passkeyRpName?: string } /** @@ -248,7 +252,21 @@ export const OpenfortProvider = ({ logger.setVerbose(verbose) }, [verbose]) - // Create or use provided client + // Create passkey handler if passkey recovery is configured (single instance for SDK and WebView) + const passkeyHandler = useMemo(() => { + if (walletConfig?.passkeyRpId) { + if (!walletConfig.passkeyRpName) { + logger.warn('passkeyRpName is required when passkeyRpId is provided for passkey recovery') + } + return new NativePasskeyHandler({ + rpId: walletConfig.passkeyRpId, + rpName: walletConfig.passkeyRpName ?? walletConfig.passkeyRpId, + }) + } + return undefined + }, [walletConfig?.passkeyRpId, walletConfig?.passkeyRpName]) + + // Create client with passkeyHandler in overrides when configured const client = useMemo(() => { const newClient = createOpenfortClient({ baseConfiguration: { @@ -258,15 +276,19 @@ export const OpenfortProvider = ({ ? new ShieldConfiguration({ shieldPublishableKey: walletConfig.shieldPublishableKey, shieldDebug: walletConfig.debug, + passkeyRpId: walletConfig.passkeyRpId, + passkeyRpName: walletConfig.passkeyRpName, }) : undefined, - overrides, + overrides: { + ...overrides, + ...(passkeyHandler && { passkeyHandler }), + }, thirdPartyAuth, }) - setDefaultClient(newClient) return newClient - }, [publishableKey, walletConfig, overrides]) + }, [publishableKey, walletConfig, overrides, thirdPartyAuth, passkeyHandler]) // Embedded state const [embeddedState, setEmbeddedState] = useState(EmbeddedState.NONE) @@ -464,6 +486,7 @@ export const OpenfortProvider = ({ { // Handle WebView status changes for debugging if (verbose) { diff --git a/src/hooks/core/index.ts b/src/hooks/core/index.ts index 8db6794..be489ef 100644 --- a/src/hooks/core/index.ts +++ b/src/hooks/core/index.ts @@ -9,4 +9,6 @@ export { useOpenfort } from './useOpenfort' export { useOpenfortClient } from './useOpenfortClient' +export { usePasskeySupport } from './usePasskeySupport' + export { useUser } from './useUser' diff --git a/src/hooks/core/usePasskeySupport.ts b/src/hooks/core/usePasskeySupport.ts new file mode 100644 index 0000000..6f946e4 --- /dev/null +++ b/src/hooks/core/usePasskeySupport.ts @@ -0,0 +1,36 @@ +import { useEffect, useState } from 'react' +import { isPasskeySupported } from '../../native/passkey' + +/** + * Hook to detect if the platform supports passkeys (WebAuthn). + * + * Note: This only checks basic passkey support, not PRF extension support. + * PRF support can only be determined during passkey creation via the + * `clientExtensionResults.prf.enabled` field in the response. + * + * @returns Object with `isSupported` boolean and `isLoading` state + */ +export function usePasskeySupport() { + const [isSupported, setIsSupported] = useState(false) + const [isLoading, setIsLoading] = useState(true) + + useEffect(() => { + async function checkSupport() { + try { + const available = await isPasskeySupported() + setIsSupported(available) + } catch { + setIsSupported(false) + } finally { + setIsLoading(false) + } + } + + checkSupport() + }, []) + + return { + isSupported, + isLoading, + } +} diff --git a/src/hooks/wallet/useEmbeddedEthereumWallet.ts b/src/hooks/wallet/useEmbeddedEthereumWallet.ts index 61c7e2c..24750e4 100644 --- a/src/hooks/wallet/useEmbeddedEthereumWallet.ts +++ b/src/hooks/wallet/useEmbeddedEthereumWallet.ts @@ -1,4 +1,10 @@ -import { AccountTypeEnum, ChainTypeEnum, type EmbeddedAccount, EmbeddedState } from '@openfort/openfort-js' +import { + AccountTypeEnum, + ChainTypeEnum, + type EmbeddedAccount, + EmbeddedState, + RecoveryMethod, +} from '@openfort/openfort-js' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useOpenfortContext } from '../../core/context' import { onError, onSuccess } from '../../lib/hookConsistency' @@ -299,10 +305,19 @@ export function useEmbeddedEthereumWallet(options: UseEmbeddedEthereumWalletOpti }, [] as EmbeddedAccount[]) return deduplicatedAccounts.map((account, index) => ({ + id: account.id, address: account.address, + chainType: ChainTypeEnum.EVM, + chainId: account.chainId, ownerAddress: account.ownerAddress, + factoryAddress: account.factoryAddress, + salt: account.salt, + accountType: account.accountType, + implementationAddress: account.implementationAddress, + createdAt: account.createdAt, implementationType: account.implementationType, - chainType: ChainTypeEnum.EVM, + recoveryMethod: account.recoveryMethod, + recoveryMethodDetails: account.recoveryMethodDetails, walletIndex: index, getProvider: async () => await getEthereumProvider(), })) @@ -365,7 +380,10 @@ export function useEmbeddedEthereumWallet(options: UseEmbeddedEthereumWalletOpti }) if (createOptions?.onSuccess) { - createOptions.onSuccess({ account: embeddedAccount, provider: ethProvider }) + createOptions.onSuccess({ + account: embeddedAccount, + provider: ethProvider, + }) } if (options.onCreateSuccess) { options.onCreateSuccess(embeddedAccount, ethProvider) @@ -468,8 +486,34 @@ export function useEmbeddedEthereumWallet(options: UseEmbeddedEthereumWalletOpti throw new OpenfortError(errorMsg, OpenfortErrorType.WALLET_ERROR) } + // Auto-detect recovery method from account if not explicitly provided + let effectiveRecoveryMethod = setActiveOptions.recoveryMethod + let effectivePasskeyId = setActiveOptions.passkeyId + + if (!effectiveRecoveryMethod && embeddedAccountToRecover.recoveryMethod) { + if (embeddedAccountToRecover.recoveryMethod === RecoveryMethod.PASSKEY) { + effectiveRecoveryMethod = 'passkey' + if (!effectivePasskeyId) { + const details = embeddedAccountToRecover.recoveryMethodDetails + if (details && 'passkeyId' in details && typeof details.passkeyId === 'string') { + effectivePasskeyId = details.passkeyId + } + } + } else if (embeddedAccountToRecover.recoveryMethod === RecoveryMethod.PASSWORD) { + effectiveRecoveryMethod = 'password' + } + } + // Build recovery params - const recoveryParams = await buildRecoveryParams({ ...setActiveOptions, userId: user?.id }, walletConfig) + const recoveryParams = await buildRecoveryParams( + { + ...setActiveOptions, + userId: user?.id, + recoveryMethod: effectiveRecoveryMethod, + passkeyId: effectivePasskeyId, + }, + walletConfig + ) // Recover the embedded wallet const embeddedAccount = await client.embeddedWallet.recover({ @@ -489,10 +533,19 @@ export function useEmbeddedEthereumWallet(options: UseEmbeddedEthereumWalletOpti ) const wallet: ConnectedEmbeddedEthereumWallet = { + id: embeddedAccount.id, address: embeddedAccount.address, + chainType: ChainTypeEnum.EVM, + chainId: embeddedAccount.chainId, ownerAddress: embeddedAccount.ownerAddress, + factoryAddress: embeddedAccount.factoryAddress, + salt: embeddedAccount.salt, + accountType: embeddedAccount.accountType, + implementationAddress: embeddedAccount.implementationAddress, + createdAt: embeddedAccount.createdAt, implementationType: embeddedAccount.implementationType, - chainType: ChainTypeEnum.EVM, + recoveryMethod: embeddedAccount.recoveryMethod, + recoveryMethodDetails: embeddedAccount.recoveryMethodDetails, walletIndex: walletIndex >= 0 ? walletIndex : 0, getProvider: async () => ethProvider, } @@ -600,10 +653,19 @@ export function useEmbeddedEthereumWallet(options: UseEmbeddedEthereumWalletOpti const accountIndex = embeddedAccounts.findIndex((acc) => acc.id === activeWalletId) return { + id: activeAccount.id, address: activeAccount.address, + chainType: ChainTypeEnum.EVM, + chainId: activeAccount.chainId, ownerAddress: activeAccount.ownerAddress, + factoryAddress: activeAccount.factoryAddress, + salt: activeAccount.salt, + accountType: activeAccount.accountType, + implementationAddress: activeAccount.implementationAddress, + createdAt: activeAccount.createdAt, implementationType: activeAccount.implementationType, - chainType: ChainTypeEnum.EVM, + recoveryMethod: activeAccount.recoveryMethod, + recoveryMethodDetails: activeAccount.recoveryMethodDetails, walletIndex: accountIndex >= 0 ? accountIndex : 0, getProvider: async () => await getEthereumProvider(), } @@ -629,11 +691,20 @@ export function useEmbeddedEthereumWallet(options: UseEmbeddedEthereumWalletOpti } if (status.status === 'connecting' || status.status === 'reconnecting' || status.status === 'loading') { - return { ...baseActions, status: 'connecting', activeWallet: activeWallet! } + return { + ...baseActions, + status: 'connecting', + activeWallet: activeWallet!, + } } if (status.status === 'error') { - return { ...baseActions, status: 'error', activeWallet, error: status.error?.message || 'Unknown error' } + return { + ...baseActions, + status: 'error', + activeWallet, + error: status.error?.message || 'Unknown error', + } } // Priority 2: Check authentication state from context @@ -650,7 +721,11 @@ export function useEmbeddedEthereumWallet(options: UseEmbeddedEthereumWalletOpti if (activeAccount && !provider) { // Have wallet but provider not initialized yet (mount recovery in progress) - return { ...baseActions, status: 'connecting', activeWallet: activeWallet! } + return { + ...baseActions, + status: 'connecting', + activeWallet: activeWallet!, + } } // Default: disconnected (authenticated but no wallet selected) diff --git a/src/hooks/wallet/useEmbeddedSolanaWallet.ts b/src/hooks/wallet/useEmbeddedSolanaWallet.ts index b21e83a..781e904 100644 --- a/src/hooks/wallet/useEmbeddedSolanaWallet.ts +++ b/src/hooks/wallet/useEmbeddedSolanaWallet.ts @@ -1,4 +1,10 @@ -import { AccountTypeEnum, ChainTypeEnum, type EmbeddedAccount, EmbeddedState } from '@openfort/openfort-js' +import { + AccountTypeEnum, + ChainTypeEnum, + type EmbeddedAccount, + EmbeddedState, + RecoveryMethod, +} from '@openfort/openfort-js' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useOpenfortContext } from '../../core/context' import { onError, onSuccess } from '../../lib/hookConsistency' @@ -261,7 +267,9 @@ export function useEmbeddedSolanaWallet(options: UseEmbeddedSolanaWalletOptions }, signMessage: async (message: string): Promise => { // Sign message using openfort-js (with hashMessage: false for Solana) - const result = await client.embeddedWallet.signMessage(message, { hashMessage: false }) + const result = await client.embeddedWallet.signMessage(message, { + hashMessage: false, + }) return result }, }) @@ -314,8 +322,12 @@ export function useEmbeddedSolanaWallet(options: UseEmbeddedSolanaWalletOptions // Build wallets list (simple deduplication by address) const wallets: ConnectedEmbeddedSolanaWallet[] = useMemo(() => { return embeddedAccounts.map((account, index) => ({ + id: account.id, address: account.address, chainType: ChainTypeEnum.SVM, + createdAt: account.createdAt, + recoveryMethod: account.recoveryMethod, + recoveryMethodDetails: account.recoveryMethodDetails, walletIndex: index, getProvider: async () => await getSolanaProvider(account), })) @@ -331,7 +343,11 @@ export function useEmbeddedSolanaWallet(options: UseEmbeddedSolanaWalletOptions // Build recovery params (only use recoveryPassword, otpCode, and userId, ignore createAdditional) const recoveryParams = await buildRecoveryParams( createOptions?.recoveryPassword || createOptions?.otpCode || user?.id - ? { recoveryPassword: createOptions?.recoveryPassword, otpCode: createOptions?.otpCode, userId: user?.id } + ? { + recoveryPassword: createOptions?.recoveryPassword, + otpCode: createOptions?.otpCode, + userId: user?.id, + } : undefined, walletConfig ) @@ -364,7 +380,10 @@ export function useEmbeddedSolanaWallet(options: UseEmbeddedSolanaWalletOptions }) if (createOptions?.onSuccess) { - createOptions.onSuccess({ account: embeddedAccount, provider: solProvider }) + createOptions.onSuccess({ + account: embeddedAccount, + provider: solProvider, + }) } if (options.onCreateSuccess) { options.onCreateSuccess(embeddedAccount, solProvider) @@ -439,8 +458,34 @@ export function useEmbeddedSolanaWallet(options: UseEmbeddedSolanaWalletOptions ) } + // Auto-detect recovery method from account if not explicitly provided + let effectiveRecoveryMethod = setActiveOptions.recoveryMethod + let effectivePasskeyId = setActiveOptions.passkeyId + + if (!effectiveRecoveryMethod && embeddedAccountToRecover.recoveryMethod) { + if (embeddedAccountToRecover.recoveryMethod === RecoveryMethod.PASSKEY) { + effectiveRecoveryMethod = 'passkey' + if (!effectivePasskeyId) { + const details = embeddedAccountToRecover.recoveryMethodDetails + if (details && 'passkeyId' in details && typeof details.passkeyId === 'string') { + effectivePasskeyId = details.passkeyId + } + } + } else if (embeddedAccountToRecover.recoveryMethod === RecoveryMethod.PASSWORD) { + effectiveRecoveryMethod = 'password' + } + } + // Build recovery params - const recoveryParams = await buildRecoveryParams({ ...setActiveOptions, userId: user?.id }, walletConfig) + const recoveryParams = await buildRecoveryParams( + { + ...setActiveOptions, + userId: user?.id, + recoveryMethod: effectiveRecoveryMethod, + passkeyId: effectivePasskeyId, + }, + walletConfig + ) // Recover the embedded wallet const embeddedAccount = await client.embeddedWallet.recover({ @@ -458,8 +503,12 @@ export function useEmbeddedSolanaWallet(options: UseEmbeddedSolanaWalletOptions ) const wallet: ConnectedEmbeddedSolanaWallet = { + id: embeddedAccount.id, address: embeddedAccount.address, chainType: ChainTypeEnum.SVM, + createdAt: embeddedAccount.createdAt, + recoveryMethod: embeddedAccount.recoveryMethod, + recoveryMethodDetails: embeddedAccount.recoveryMethodDetails, walletIndex: walletIndex >= 0 ? walletIndex : 0, getProvider: async () => solProvider, } @@ -522,8 +571,12 @@ export function useEmbeddedSolanaWallet(options: UseEmbeddedSolanaWalletOptions const accountIndex = embeddedAccounts.findIndex((acc) => acc.id === activeWalletId) return { + id: activeAccount.id, address: activeAccount.address, chainType: ChainTypeEnum.SVM, + createdAt: activeAccount.createdAt, + recoveryMethod: activeAccount.recoveryMethod, + recoveryMethodDetails: activeAccount.recoveryMethodDetails, walletIndex: accountIndex >= 0 ? accountIndex : 0, getProvider: async () => await getSolanaProvider(activeAccount), } @@ -547,11 +600,16 @@ export function useEmbeddedSolanaWallet(options: UseEmbeddedSolanaWalletOptions } if (status.status === 'connecting' || status.status === 'reconnecting' || status.status === 'loading') { - return { ...baseActions, status: 'connecting' } + return { ...baseActions, status: 'connecting', activeWallet } } if (status.status === 'error') { - return { ...baseActions, status: 'error', activeWallet, error: status.error?.message || 'Unknown error' } + return { + ...baseActions, + status: 'error', + activeWallet, + error: status.error?.message || 'Unknown error', + } } // Priority 2: Check authentication state from context @@ -568,7 +626,7 @@ export function useEmbeddedSolanaWallet(options: UseEmbeddedSolanaWalletOptions if (activeAccount && !provider) { // Have wallet but provider not initialized yet (mount recovery in progress) - return { ...baseActions, status: 'connecting' } + return { ...baseActions, status: 'connecting', activeWallet } } // Default: disconnected (authenticated but no wallet selected) diff --git a/src/hooks/wallet/utils.ts b/src/hooks/wallet/utils.ts index 80f230d..be428bb 100644 --- a/src/hooks/wallet/utils.ts +++ b/src/hooks/wallet/utils.ts @@ -81,16 +81,49 @@ async function resolveEncryptionSession( * @internal */ export async function buildRecoveryParams( - options: { recoveryPassword?: string; otpCode?: string; userId?: string } | undefined, + options: + | { + recoveryPassword?: string + otpCode?: string + userId?: string + recoveryMethod?: 'automatic' | 'password' | 'passkey' + passkeyId?: string + } + | undefined, walletConfig?: EmbeddedWalletConfiguration ): Promise { - if (options?.recoveryPassword) { + // If passkey recovery method is explicitly requested + if (options?.recoveryMethod === 'passkey') { + // If passkeyId is provided, use it for recovery + if (options.passkeyId) { + return { + recoveryMethod: RecoveryMethod.PASSKEY, + passkeyInfo: { + passkeyId: options.passkeyId, + }, + } + } + // If no passkeyId, this is a creation request - SDK will create the passkey + return { + recoveryMethod: RecoveryMethod.PASSKEY, + } + } + + // If password recovery method is explicitly requested or password is provided + if (options?.recoveryMethod === 'password' || options?.recoveryPassword) { + if (!options?.recoveryPassword) { + throw new OpenfortError( + 'Recovery password is required when using password recovery method', + OpenfortErrorType.WALLET_ERROR + ) + } return { recoveryMethod: RecoveryMethod.PASSWORD, password: options.recoveryPassword, } } + // Default to automatic recovery return { recoveryMethod: RecoveryMethod.AUTOMATIC, encryptionSession: await resolveEncryptionSession(walletConfig, options?.otpCode, options?.userId), diff --git a/src/index.ts b/src/index.ts index 0f67472..f745c7e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -42,8 +42,9 @@ export * from './constants' export * from './core' // Re-export all hooks export * from './hooks' - // Re-export native functionality export * from './native' // Re-export all types from the main types module export * from './types' +// Re-export RecoveryMethodDetails extracted from EmbeddedAccount (not directly exported from @openfort/openfort-js) +export type { RecoveryMethodDetails } from './types/wallet' diff --git a/src/native/index.ts b/src/native/index.ts index 25122f4..964d6f0 100644 --- a/src/native/index.ts +++ b/src/native/index.ts @@ -1,5 +1,4 @@ // WebView integration - export type { AppleAuthResult, OAuthResult, @@ -14,6 +13,9 @@ export { openOAuthSession, parseOAuthUrl, } from './oauth' +export type { NativePasskeyHandlerConfig, PasskeysAPI } from './passkey' +// Passkey handler and support checks +export { getPasskeyDiagnostics, isPasskeySupported, NativePasskeyHandler } from './passkey' export type { SecureStorageMessage, SecureStorageResponse, diff --git a/src/native/passkey.ts b/src/native/passkey.ts new file mode 100644 index 0000000..c1e625a --- /dev/null +++ b/src/native/passkey.ts @@ -0,0 +1,445 @@ +import { + type IPasskeyHandler, + PasskeyAssertionFailedError, + PasskeyCreationFailedError, + PasskeyPRFNotSupportedError, + PasskeySeedInvalidError, + PasskeyUserCancelledError, +} from '@openfort/openfort-js' +import { logger } from '../lib/logger' + +/** + * Utility functions for passkey operations in React Native. + * Handles base64/base64url encoding, key extraction, and challenge generation. + */ +const PasskeyUtils = { + /** Valid byte lengths for derived keys (AES-128, AES-192, AES-256) */ + validByteLengths: [16, 24, 32], + + /** + * Validates that the key byte length is valid for AES encryption. + * @throws Error if length is not 16, 24, or 32 + */ + validateKeyByteLength(length: number): void { + if (!this.validByteLengths.includes(length)) { + throw new Error(`Invalid key byte length ${length}. Must be 16, 24, or 32.`) + } + }, + + /** + * Generates a random 32-byte challenge for WebAuthn operations. + */ + generateChallenge(): Uint8Array { + const challenge = new Uint8Array(32) + if (typeof crypto !== 'undefined' && crypto.getRandomValues) { + crypto.getRandomValues(challenge) + } else { + // Fallback for environments without crypto.getRandomValues + for (let i = 0; i < 32; i++) { + challenge[i] = Math.floor(Math.random() * 256) + } + } + return challenge + }, + + /** + * Converts ArrayBuffer or Uint8Array to base64url string. + * Base64URL uses '-' and '_' instead of '+' and '/', and omits padding '='. + */ + arrayBufferToBase64URL(buffer: ArrayBuffer | Uint8Array): string { + const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer) + let binary = '' + for (const byte of bytes) { + binary += String.fromCharCode(byte) + } + const base64 = btoa(binary) + return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '') + }, + + /** + * Converts base64url string to Uint8Array. + */ + base64URLToUint8Array(base64url: string): Uint8Array { + // Convert base64url to base64 + let base64 = base64url.replace(/-/g, '+').replace(/_/g, '/') + // Add padding if needed + while (base64.length % 4) { + base64 += '=' + } + const binary = atob(base64) + const bytes = new Uint8Array(binary.length) + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i) + } + return bytes + }, + + /** + * Converts standard base64 to base64url format. + * This is idempotent - safe to call on strings already in base64url format. + */ + base64ToBase64URL(base64: string): string { + return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '') + }, + + /** + * Extracts the first N bytes from a PRF result for use as key material. + */ + extractRawKeyBytes(prfResult: Uint8Array, length: number): Uint8Array { + return prfResult.slice(0, length) + }, +} + +/** + * Result from passkey credential creation. + */ +interface PasskeyCredentialResult { + id: string + rawId?: string + type: string + clientExtensionResults?: { + prf?: { + results?: { + first?: unknown // Can be string, ArrayBuffer, or number[] + } + } + } + response?: { + attestationObject?: string + clientDataJSON?: string + } +} + +/** + * Result from passkey assertion (get). + */ +interface PasskeyAssertionResult { + id: string + type: string + clientExtensionResults?: { + prf?: { + results?: { + first?: unknown + } + } + } +} + +/** Resolved API from react-native-passkeys (module.Passkeys ?? module). Library may export sync or async isSupported. */ +export type PasskeysAPI = { + create?: (options: PublicKeyCredentialCreationOptions) => Promise + get?: (options: PublicKeyCredentialRequestOptions) => Promise + /** Sync on native (iOS/Android), sync on web; may be function or boolean. */ + isSupported?: (() => boolean) | (() => Promise) | boolean +} + +let passkeysModule: (PasskeysAPI & { Passkeys?: PasskeysAPI }) | null = null +let passkeysLoadAttempted = false +let passkeysLoadError: Error | null = null + +/** + * Returns the passkeys API (create, get, isSupported). Resolves module.Passkeys ?? module once. + * Returns null if the module failed to load. + */ +function getPasskeysAPI(): PasskeysAPI | null { + if (passkeysLoadAttempted) { + return passkeysLoadError ? null : passkeysModule ? (passkeysModule.Passkeys ?? passkeysModule) : null + } + passkeysLoadAttempted = true + try { + passkeysModule = require('react-native-passkeys') + return passkeysModule ? (passkeysModule.Passkeys ?? passkeysModule) : null + } catch (error) { + passkeysLoadError = error instanceof Error ? error : new Error(String(error)) + return null + } +} + +/** + * Returns diagnostic information about passkey support. + * Useful for debugging why passkeys may not be available. + */ +export function getPasskeyDiagnostics(): { + isSupported: boolean + loadError: Error | null + moduleLoaded: boolean +} { + const api = getPasskeysAPI() + return { + isSupported: api !== null && api.isSupported !== undefined, + loadError: passkeysLoadError, + moduleLoaded: passkeysLoadAttempted && passkeysLoadError === null, + } +} + +/** + * Checks if the device supports passkeys (WebAuthn). Uses the library's isSupported() only — no credential creation. + * Normalizes sync/async and function/boolean from react-native-passkeys. + */ +export async function isPasskeySupported(): Promise { + const api = getPasskeysAPI() + if (!api || api.isSupported == null) { + return false + } + const supported = api.isSupported + if (typeof supported === 'boolean') { + return supported + } + if (typeof supported === 'function') { + const result = supported() + return result instanceof Promise ? result : Promise.resolve(result) + } + return false +} + +export interface NativePasskeyHandlerConfig { + rpId?: string + rpName?: string + timeout?: number + derivedKeyLengthBytes?: number +} + +// Type definitions for react-native-passkeys +interface PublicKeyCredentialCreationOptions { + challenge: string + rp: { id: string; name: string } + user: { id: string; name: string; displayName: string } + pubKeyCredParams: Array<{ type: string; alg: number }> + authenticatorSelection: { + authenticatorAttachment?: string + residentKey?: string + requireResidentKey?: boolean + userVerification?: string + } + excludeCredentials?: Array<{ id: string; type: string }> + extensions?: { prf?: { eval?: { first: string } } } + timeout?: number + attestation?: string +} + +interface PublicKeyCredentialRequestOptions { + challenge: string + rpId: string + allowCredentials: Array<{ id: string; type: string }> + userVerification: string + extensions?: { prf?: { eval?: { first: string } } } + timeout?: number +} + +/** + * NativePasskeyHandler implements IPasskeyHandler using react-native-passkeys (create/get) + * as the native equivalent of navigator.credentials.create/get. Same contract as openfort-js + * PasskeyHandler; key is returned to the SDK/Shield like on web. + */ +export class NativePasskeyHandler implements IPasskeyHandler { + private readonly rpId?: string + private readonly rpName?: string + private readonly timeout: number + private readonly derivedKeyLengthBytes: number + + constructor(config: NativePasskeyHandlerConfig) { + this.rpId = config.rpId + this.rpName = config.rpName + this.timeout = config.timeout ?? 60_000 + this.derivedKeyLengthBytes = config.derivedKeyLengthBytes ?? 32 + + PasskeyUtils.validateKeyByteLength(this.derivedKeyLengthBytes) + } + + /** + * Normalizes prf.results.first from the native module to Uint8Array. + * On Android, the bridge may return base64 string or array of numbers. + */ + private normalizePRFResult(first: unknown): Uint8Array { + if (typeof first === 'string') { + return PasskeyUtils.base64URLToUint8Array(first) + } + if (first instanceof ArrayBuffer) { + return new Uint8Array(first) + } + if (ArrayBuffer.isView(first)) { + return new Uint8Array(first.buffer, first.byteOffset, first.byteLength) + } + if (Array.isArray(first) || (typeof first === 'object' && first !== null && 'length' in first)) { + return new Uint8Array(first as ArrayLike) + } + throw new Error('PRF result: expected base64 string, ArrayBuffer, TypedArray, or array of numbers') + } + + /** + * Extracts key bytes from PRF result and returns as base64url string. + * Validates that the PRF result has sufficient entropy for the requested key length. + */ + private extractKeyBytes(prfResultBytes: Uint8Array): string { + // Validate PRF result has sufficient entropy + if (prfResultBytes.length < this.derivedKeyLengthBytes) { + throw new Error( + `PRF result too short: got ${prfResultBytes.length} bytes, need at least ${this.derivedKeyLengthBytes} bytes` + ) + } + const keyBytes = PasskeyUtils.extractRawKeyBytes(prfResultBytes, this.derivedKeyLengthBytes) + return PasskeyUtils.arrayBufferToBase64URL(keyBytes) + } + + /** + * Creates a passkey and derives a key using the PRF extension. + */ + async createPasskey(config: { + id: string + displayName: string + seed: string + }): Promise<{ id: string; displayName?: string; key?: string }> { + if (!this.rpId || !this.rpName) { + throw new Error('rpId and rpName must be configured') + } + + // Validate seed is non-empty for PRF entropy + if (!config.seed || config.seed.trim().length === 0) { + throw new PasskeySeedInvalidError() + } + + const challenge = PasskeyUtils.generateChallenge() + // Android Credentials API requires base64url for challenge + const challengeBase64URL = PasskeyUtils.arrayBufferToBase64URL(challenge) + const userIdBytes = new TextEncoder().encode(config.id) + // Android Credentials API requires base64url for user.id + const userIdBase64URL = PasskeyUtils.arrayBufferToBase64URL(userIdBytes) + + const publicKey: PublicKeyCredentialCreationOptions = { + challenge: challengeBase64URL, + rp: { id: this.rpId, name: this.rpName }, + user: { + id: userIdBase64URL, + name: config.id, + displayName: config.displayName, + }, + pubKeyCredParams: [ + { type: 'public-key', alg: -7 }, + { type: 'public-key', alg: -257 }, + ], + authenticatorSelection: { + residentKey: 'required', + userVerification: 'required', + }, + excludeCredentials: [], + // PRF extension: react-native-passkeys expects all inputs as base64url + extensions: { + prf: { + eval: { + first: PasskeyUtils.arrayBufferToBase64URL(new TextEncoder().encode(config.seed)), + }, + }, + }, + timeout: this.timeout, + attestation: 'none', + } + + const api = getPasskeysAPI() + if (!api?.create || typeof api.create !== 'function') { + throw new Error('react-native-passkeys module not available') + } + + let credential: PasskeyCredentialResult | null + try { + credential = await api.create(publicKey) + } catch (e) { + // Re-throw known error types + if (e instanceof PasskeyUserCancelledError) throw e + if (e instanceof PasskeySeedInvalidError) throw e + throw new PasskeyCreationFailedError( + e instanceof Error ? e.message : 'Unknown error', + e instanceof Error ? e : undefined + ) + } + + if (!credential) { + // Null result typically indicates user cancellation + throw new PasskeyUserCancelledError() + } + + const prfResults = credential.clientExtensionResults?.prf + if (!prfResults?.results?.first) { + // Log warning about orphaned passkey credential + logger.warn( + 'Passkey created but PRF extension failed. ' + + 'A passkey credential may exist on the device that cannot be used for wallet recovery. ' + + `Credential ID: ${credential.id}` + ) + throw new PasskeyPRFNotSupportedError() + } + + const prfResultBytes = this.normalizePRFResult(prfResults.results.first) + const key = this.extractKeyBytes(prfResultBytes) + + return { + id: credential.id, + displayName: config.displayName, + key, + } + } + + /** + * Derives and exports key material from an existing passkey as base64url string. + */ + async deriveAndExportKey(config: { id: string; seed: string }): Promise { + if (!this.rpId) { + throw new Error('rpId must be configured') + } + + // Validate seed is non-empty for PRF entropy + if (!config.seed || config.seed.trim().length === 0) { + throw new PasskeySeedInvalidError() + } + + const challenge = PasskeyUtils.generateChallenge() + const challengeBase64URL = PasskeyUtils.arrayBufferToBase64URL(challenge) + // Always normalize to base64url - this is idempotent for strings already in base64url format + const credentialId = PasskeyUtils.base64ToBase64URL(config.id) + + const publicKey: PublicKeyCredentialRequestOptions = { + challenge: challengeBase64URL, + rpId: this.rpId, + allowCredentials: [{ id: credentialId, type: 'public-key' }], + userVerification: 'required', + extensions: { + prf: { + eval: { + first: PasskeyUtils.arrayBufferToBase64URL(new TextEncoder().encode(config.seed)), + }, + }, + }, + timeout: this.timeout, + } + + const api = getPasskeysAPI() + if (!api?.get || typeof api.get !== 'function') { + throw new Error('react-native-passkeys module not available') + } + + let assertion: PasskeyAssertionResult | null + try { + assertion = await api.get(publicKey) + } catch (e) { + // Re-throw known error types + if (e instanceof PasskeyUserCancelledError) throw e + if (e instanceof PasskeySeedInvalidError) throw e + throw new PasskeyAssertionFailedError( + e instanceof Error ? e.message : 'Unknown error', + e instanceof Error ? e : undefined + ) + } + + if (!assertion) { + // Null result typically indicates user cancellation + throw new PasskeyUserCancelledError() + } + + const prfResults = assertion.clientExtensionResults?.prf + if (!prfResults?.results?.first) { + throw new PasskeyPRFNotSupportedError() + } + + const prfResultBytes = this.normalizePRFResult(prfResults.results.first) + return this.extractKeyBytes(prfResultBytes) + } +} diff --git a/src/native/webview.tsx b/src/native/webview.tsx index 92818de..d3a98c1 100644 --- a/src/native/webview.tsx +++ b/src/native/webview.tsx @@ -19,6 +19,8 @@ interface EmbeddedWalletWebViewProps { isClientReady: boolean /** Callback when WebView proxy status changes */ onProxyStatusChange?: (status: 'loading' | 'loaded' | 'reloading') => void + /** Enable WebView debugging (allows inspection via Safari/Chrome dev tools) */ + debug?: boolean } /** @@ -28,11 +30,7 @@ interface EmbeddedWalletWebViewProps { * * @param props - Component props, see {@link EmbeddedWalletWebViewProps} */ -export const EmbeddedWalletWebView: React.FC = ({ - client, - isClientReady, - onProxyStatusChange, -}) => { +export const EmbeddedWalletWebView: React.FC = ({ client, onProxyStatusChange, debug }) => { const webViewRef = useRef(null) // Handle app state changes to monitor WebView health @@ -68,7 +66,6 @@ export const EmbeddedWalletWebView: React.FC = ({ // Set up WebView reference with client immediately when both are available useEffect(() => { if (webViewRef.current) { - // Message poster with Uint8Array preprocessing for React Native const messagePoster = { postMessage: (message: string) => { webViewRef.current?.postMessage(message) @@ -76,7 +73,7 @@ export const EmbeddedWalletWebView: React.FC = ({ } client.embeddedWallet.setMessagePoster(messagePoster) } - }, [client, isClientReady]) + }, [client]) // Clean message handler using the new penpal bridge const handleMessage = useCallback( @@ -126,7 +123,8 @@ export const EmbeddedWalletWebView: React.FC = ({ source={{ uri: client.embeddedWallet.getURL(), }} - webviewDebuggingEnabled={true} + // Enable debugging when explicitly enabled via walletConfig.debug + webviewDebuggingEnabled={debug} cacheEnabled={false} injectedJavaScriptObject={{ shouldUseAppBackedStorage: true }} cacheMode="LOAD_NO_CACHE" @@ -196,7 +194,11 @@ export const WebViewUtils = { * @param message - JSON string message to validate * @returns Validation result with parsed data or error information */ - validateMessage(message: string): { isValid: boolean; data?: any; error?: string } { + validateMessage(message: string): { + isValid: boolean + data?: any + error?: string + } { try { const parsed = JSON.parse(message) diff --git a/src/types/index.ts b/src/types/index.ts index 3404f87..908e7db 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -7,6 +7,16 @@ export interface UseOpenfort { error: Error | null } +// Passkey error types (re-exported from @openfort/openfort-js) +export { + PASSKEY_ERROR_CODES, + PasskeyAssertionFailedError, + PasskeyCreationFailedError, + type PasskeyErrorCode, + PasskeyPRFNotSupportedError, + PasskeySeedInvalidError, + PasskeyUserCancelledError, +} from '@openfort/openfort-js' // Authentication types export type { AuthSuccessCallback, diff --git a/src/types/wallet.ts b/src/types/wallet.ts index a3d3dca..3700f58 100644 --- a/src/types/wallet.ts +++ b/src/types/wallet.ts @@ -1,4 +1,16 @@ -import type { AccountTypeEnum, ChainTypeEnum, EmbeddedAccount, RecoveryParams } from '@openfort/openfort-js' +import type { + AccountTypeEnum, + ChainTypeEnum, + EmbeddedAccount, + RecoveryMethod, + RecoveryParams, +} from '@openfort/openfort-js' + +/** + * Recovery method details extracted from EmbeddedAccount + */ +export type RecoveryMethodDetails = EmbeddedAccount['recoveryMethodDetails'] + import type { Hex } from './hex' import type { OpenfortHookOptions } from './hookOption' import type { OpenfortError } from './openfortError' @@ -122,11 +134,35 @@ export interface OpenfortEmbeddedSolanaWalletProvider { * Connected Ethereum wallet */ export type ConnectedEmbeddedEthereumWallet = { + /** Account ID */ + id: string + /** Account address */ address: string + /** Chain type (always EVM) */ + chainType: ChainTypeEnum.EVM + /** Chain ID */ + chainId?: number + /** Owner address (for smart accounts) */ ownerAddress?: string + /** Factory address (for smart accounts) */ + factoryAddress?: string + /** Salt (for smart accounts) */ + salt?: string + /** Account type (EOA, Smart Account, Delegated) */ + accountType: AccountTypeEnum + /** Implementation address (for smart accounts) */ + implementationAddress?: string + /** Creation timestamp */ + createdAt?: number + /** Implementation type */ implementationType?: string - chainType: ChainTypeEnum.EVM + /** Recovery method used for this wallet */ + recoveryMethod?: RecoveryMethod + /** Recovery method details (e.g., passkey info) */ + recoveryMethodDetails?: RecoveryMethodDetails + /** Index in the wallets array */ walletIndex: number + /** Get the EIP-1193 provider for this wallet */ getProvider: () => Promise } @@ -134,9 +170,21 @@ export type ConnectedEmbeddedEthereumWallet = { * Connected Solana wallet */ export type ConnectedEmbeddedSolanaWallet = { + /** Account ID */ + id: string + /** Account address (public key) */ address: string + /** Chain type (always SVM) */ chainType: ChainTypeEnum.SVM + /** Creation timestamp */ + createdAt?: number + /** Recovery method used for this wallet */ + recoveryMethod?: RecoveryMethod + /** Recovery method details (e.g., passkey info) */ + recoveryMethodDetails?: RecoveryMethodDetails + /** Index in the wallets array */ walletIndex: number + /** Get the Solana provider for this wallet */ getProvider: () => Promise } @@ -163,6 +211,10 @@ export type CreateEthereumWalletOptions = { otpCode?: string accountType?: AccountTypeEnum policyId?: string + /** Recovery method to use: 'automatic', 'password', or 'passkey' */ + recoveryMethod?: 'automatic' | 'password' | 'passkey' + /** Passkey ID for passkey recovery (required when recoveryMethod is 'passkey' for recovery) */ + passkeyId?: string } & OpenfortHookOptions /** @@ -183,6 +235,10 @@ export type SetActiveEthereumWalletOptions = { recoveryPassword?: string /** OTP code for Shield verification when using automatic recovery */ otpCode?: string + /** Recovery method to use: 'automatic', 'password', or 'passkey' */ + recoveryMethod?: 'automatic' | 'password' | 'passkey' + /** Passkey ID for passkey recovery (required when recoveryMethod is 'passkey' for recovery) */ + passkeyId?: string } & OpenfortHookOptions /** @@ -221,6 +277,10 @@ export type CreateSolanaEmbeddedWalletOpts = { * Create additional wallet if one already exists */ createAdditional?: boolean + /** Recovery method to use: 'automatic', 'password', or 'passkey' */ + recoveryMethod?: 'automatic' | 'password' | 'passkey' + /** Passkey ID for passkey recovery (required when recoveryMethod is 'passkey' for recovery) */ + passkeyId?: string } /** @@ -254,6 +314,10 @@ export type SetActiveSolanaWalletOptions = { recoveryPassword?: string /** OTP code for Shield verification when using automatic recovery */ otpCode?: string + /** Recovery method to use: 'automatic', 'password', or 'passkey' */ + recoveryMethod?: 'automatic' | 'password' | 'passkey' + /** Passkey ID for passkey recovery (required when recoveryMethod is 'passkey' for recovery) */ + passkeyId?: string } & OpenfortHookOptions // ============================================================================