From f22cf32c4f6c1854a803a56fd815bb6b9c5544d6 Mon Sep 17 00:00:00 2001 From: Egge Date: Fri, 28 Jun 2024 11:22:23 +0200 Subject: [PATCH 01/39] updated tests --- test/utils.test.ts | 138 +++++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 79 deletions(-) diff --git a/test/utils.test.ts b/test/utils.test.ts index c43b36fe9..15fa721aa 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -1,4 +1,4 @@ -import { AmountPreference } from '../src/model/types/index.js'; +import { AmountPreference, Token } from '../src/model/types/index.js'; import * as utils from '../src/utils.js'; import { PUBKEYS } from './consts.js'; @@ -47,87 +47,20 @@ describe('test decode token', () => { test('testing v1 Token', () => { const token = 'W3siaWQiOiIwTkkzVFVBczFTZnkiLCJhbW91bnQiOjIsInNlY3JldCI6Ild6ZC9vNUVHdmVKb3hTQVlGcjZ1U3lnUmFWSUFrOFc4MXNLTlRxdVd4UjQ9IiwiQyI6IjAzNWNiZmQwOTNiOWZlMWRjNjU2MGEwNDM3YzQyNDQxZjA0ZDIyYzk4MDY2NGMyNGExMGZlZGFiNTlmZWY0YmZjOSJ9LHsiaWQiOiIwTkkzVFVBczFTZnkiLCJhbW91bnQiOjQsInNlY3JldCI6InU0N2lWUkhneUNuUFhCNWxOdFpGaTBOeHpPZ1lyRk1WODV2aFpyRThIbWM9IiwiQyI6IjAyNThiYmZkZWJmZGQzYjk0OTljZDk1YzFkMWZiYTVjZTQ1MWFjOGNlZTE0NzM1Yzk2MGFiMDc1ZmI2ZTQ4ZjBkYyJ9LHsiaWQiOiIwTkkzVFVBczFTZnkiLCJhbW91bnQiOjY0LCJzZWNyZXQiOiJ1YTFaT0hjeVB3T0M0UUxPaWthQVV1MThJM2pEUDJCSVNYREFGcW91N1VNPSIsIkMiOiIwMjU2MWNhNjcyNTdlNzdhNjNjN2U3NWQ4MGVkYTI3ZDlhMmEyYzUxZTA0NGM4ZjhmODVlNzc0OTZlMGRlM2U2NWIifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50IjoxLCJzZWNyZXQiOiJ5ZTlNRCtaQ25VUHlHOTBscmYyZ2tudnA3N2I4V05wNUxRT2ZtcERjRGNFPSIsIkMiOiIwM2UwN2M1NjExNzcwMmNmODg3MDFlYjAyOTM2YjA5MDNhZmEyMTQwZDcwNTY1N2ZkODVkM2YxZWI5MzRiYTBjYzMifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50IjoyLCJzZWNyZXQiOiJIUHpzRmZPUDFWRU1BMW8vTnFHVXFhRXdaV2RiN3VERzM4T1grLzlZTURzPSIsIkMiOiIwMmQ3ZDE1YTBhZmIyNThjMjlhZDdmOWY4N2ZmMzIxZWRmNTgyOTM0ZWI0NWExNTE2MjhiNTJjMDExZjQ2MWZkOGEifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50IjoxLCJzZWNyZXQiOiJnMVR1YXdha1RVQkJBTW9tZGpDVHkrRENNTnBaUmd3dWluNXB5V2xoTVVNPSIsIkMiOiIwMzU4Y2IxMGE5NWEzY2E1YmE5MTc5MTllMWNhODA1NjZmMTg5NTI4Njk1MTJjYWFjMDlmYmQ5MGYxN2QyZTZlYmEifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50IjoyLCJzZWNyZXQiOiJRMTFyamNXWk55Q2dkRmxqRThaNkdwNFhDYllKcndzRGhncXVQOTU1VWU0PSIsIkMiOiIwMjAxNjBmODIwNGU4MGIxNDg4NmFlMzZjMzRiMjI3ODllMzMxZmM5MjVhNGMwOGE3ZWYxZDZjYzMyYTIwNjZjZWUifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50Ijo4LCJzZWNyZXQiOiI1MVZrUXFYT2kwM0k2a0pzM0tlSEI0OVVCQTFSRktrWnMyMFljZEtOSW1JPSIsIkMiOiIwMjZiYWU2YTgzOWE3OTdjNmU5NGZlNGM5MWZlNTIwOGU4MDE3MTg2Y2NkMDk0ZmI4ZTNkZjYyNjAyZWJmMjczMjUifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50IjoxNiwic2VjcmV0IjoiVk4ySlMwUENKdGQ3MjJUTXUxdGFxNUZSMXg0dDlXM28xNndWRGVweXBxYz0iLCJDIjoiMDIxMmM4ZGE5NWE4NDEyYjgyMDE4MTgxNzQxZWY1YWQ0ZjYzMTU1NjBhMWFmODM5ZjMxOTU4NTcwZTVlYzI2ZDQyIn1d'; - - const result = utils.getDecodedToken(token); - expect(result.token[0].proofs.reduce((c, p) => c + p.amount, 0)).toEqual(100); - expect(result.token[0].mint).toStrictEqual(''); - }); - test('test corrupt v1 token', () => { - const token = - 'W3siaWQiOiIwTkkzVFVBczFTZnkiLCJhbW91bnQiOjIsInNlY3JldCI6Ild6ZC9vNUVHdmVKb3hTQVlGcjZ1U3lnUmFWSUFrOFc4MXNLTlRxdVd4UjQ9IiwiQyI6IjAzNWNiZmQwOTNiOWZlMWRjNjU2MGEwNDM3YzQyNDQxZjA0ZDIyYzk4MDY2NGMyNGExMGZlZGFiNTlmZWY0YmZjOSJ9LHsiaWQiOiIwTkkzVFVBczFTZnkiLCJhbW91bnQiOjQsInNlY3JldCI6InU0N2lWUkhneUNuUFhCNWxOdFpGaTBOIkMiOiIwMmQ3ZDE1YTBhZmIyNThjMjlhZDdmOWY4N2ZmMzIxZWRmNTgyOTM0ZWI0NWExNTE2MjhiNTJjMDExZjQ2MWZkOGEifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50IjoxLCJzZWNyZXQiOiJnMVR1YXdha1RVQkJBTW9tZGpDVHkrRENNTnBaUmd3dWluNXB5V2xoTVVNPSIsIkMiOiIwMzU4Y2IxMGE5NWEzY2E1YmE5MTc5MTllMWNhODA1NjZmMTg5NTI4Njk1MTJjYWFjMDlmYmQ5MGYxN2QyZTZlYmEifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50IjoyLCJzZWNyZXQiOiJRMTFyamNXWk55Q2dkRmxqRThaNkdwNFhDYllKcndzRGhncXVQOTU1VWU0PSIsIkMiOiIwMjAxNjBmODIwNGU4MGIxNDg4NmFlMzZjMzRiMjI3ODllMzMxZmM5MjVhNGMwOGE3ZWYxZDZjYzMyYTIwNjZjZWUifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50Ijo4LCJzZWNyZXQiOiI1MVZrUXFYT2kwM0k2a0pzM0tlSEI0OVVCQTFSRktrWnMyMFljZEtOSW1JPSIsIkMiOiIwMjZiYWU2YTgzOWE3OTdjNmU5NGZlNGM5MWZlNTIwOGU4MDE3MTg2Y2NkMDk0ZmI4ZTNkZjYyNjAyZWJmMjczMjUifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50IjoxNiwic2VjcmV0IjoiVk4ySlMwUENKdGQ3MjJUTXUxdGFxNUZSMXg0dDlXM28xNndWRGVweXBxYz0iLCJDIjoiMDIxMmM4ZGE5NWE4NDEyYjgyMDE4MTgxNzQxZWY1YWQ0ZjYzMTU1NjBhMWFmODM5ZjMxOTU4NTcwZTVlYzI2ZDQyIn1d'; - expect(() => utils.getDecodedToken(token)).toThrowError(); + let result: Token | undefined; + expect(() => { + result = utils.getDecodedToken(token); + }).toThrow(); + expect(result).toBe(undefined); }); test('testing v2 Token', async () => { const token = 'eyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJpZCI6IkkyeU4raVJZZmt6VCIsImFtb3VudCI6MSwic2VjcmV0IjoiOTd6Zm1tYUdmNWs4TWcwZ2FqcG5ibXBlcnZUdEVlRTh3d0tyaTdyV3BVcz0iLCJDIjoiMDIxOTUwODFlNjIyZjk4YmZjMTlhMDVlYmUyMzQxZDk1NWMwZDEyNTg4YzU5NDhjODU4ZDA3YWRlYzAwN2JjMWU0In1dLCJtaW50IjoiaHR0cDovL2xvY2FsaG9zdDozMzM4In1dfQ'; - - const result = utils.getDecodedToken(token); - expect(result).toStrictEqual({ - token: [ - { - proofs: [ - { - id: 'I2yN+iRYfkzT', - amount: 1, - secret: '97zfmmaGf5k8Mg0gajpnbmpervTtEeE8wwKri7rWpUs=', - C: '02195081e622f98bfc19a05ebe2341d955c0d12588c5948c858d07adec007bc1e4' - } - ], - mint: 'http://localhost:3338' - } - ] - }); - }); - test('testing v2 Token 2', () => { - const token = - 'eyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJpZCI6IjBOSTNUVUFzMVNmeSIsImFtb3VudCI6MSwic2VjcmV0Ijoia3hxWFlwYkNWb0l1eDRsbVdJRFh4M29NMi83S1ZzaHFqSklJZXh0cU1hVT0iLCJDIjoiMDJhNDIxNDBkMWJiZDU5Y2E0YzViYTllYjczZDAyMGYzMWY2OGY0ZTMwNzhmZDNhZjFlZTY0ZWJlY2U1MmI2ZWRhIn1dLCJtaW50IjoiaHR0cDovL2xvY2FsaG9zdDozMzM4In1dfQ'; - - const result = utils.getDecodedToken(token); - expect(result).toStrictEqual({ - token: [ - { - proofs: [ - { - id: '0NI3TUAs1Sfy', - amount: 1, - secret: 'kxqXYpbCVoIux4lmWIDXx3oM2/7KVshqjJIIextqMaU=', - C: '02a42140d1bbd59ca4c5ba9eb73d020f31f68f4e3078fd3af1ee64ebece52b6eda' - } - ], - mint: 'http://localhost:3338' - } - ] - }); - }); - test('test corrupt v2 token', () => { - const token = - 'W3siaWQiOiIwTkkzVFVBczFTZnkiLCJhbW91bnQiOjIsInNlY3JldCI6Ild6ZC9vNUVHdmVKb3hTQVlGcjZ1U3lnUmFWSUFrOFc4MXNLTlRxdVd4UjQ9IiwiQyI6IjAzNWNiZmQwOTNiOWZlMWRjNjU2MGEwNDM3YzQyNDQxZjA0ZDIyYzk4MDY2NGMyNGExMGZlZGFiNTlmZWY0YmZjOSJ9LHsiaWQiOiIwTkkzVFVBczFTZnkiLCJhbW91bnQiOjQsInNlY3JldCI6InU0N2lWUkhneUNuUFhCNWxOdFpGaTBOIkMiOiIwMmQ3ZDE1YTBhZmIyNThjMjlhZDdmOWY4N2ZmMzIxZWRmNTgyOTM0ZWI0NWExNTE2MjhiNTJjMDExZjQ2MWZkOGEifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50IjoxLCJzZWNyZXQiOiJnMVR1YXdha1RVQkJBTW9tZGpDkMiOiIwMjZiYWU2YTgzOWE3OTdjNmU5NGZlNGM5MWZlNTIwOGU4MDE3MTg2Y2NkMDk0ZmI4ZTNkZjYyNjAyZWJmMjczMjUifSx7ImlkIjoiME5JM1RVQXMxU2Z5IiwiYW1vdW50IjoxNiwic2VjcmV0IjoiVk4ySlMwUENKdGQ3MjJUTXUxdGFxNUZSMXg0dDlXM28xNndWRGVweXBxYz0iLCJDIjoiMDIxMmM4ZGE5NWE4NDEyYjgyMDE4MTgxNzQxZWY1YWQ0ZjYzMTU1NjBhMWFmODM5ZjMxOTU4NTcwZTVlYzI2ZDQyIn1d'; - - expect(() => utils.getDecodedToken(token)).toThrowError(); - }); -}); - -describe('test encode token', () => { - test('testing v3 Token', async () => { - const token = - 'cashuAeyJ0b2tlbiI6W3sibWludCI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzMzOCIsInByb29mcyI6W3siaWQiOiJJMnlOK2lSWWZrelQiLCJhbW91bnQiOjEsInNlY3JldCI6Ijk3emZtbWFHZjVrOE1nMGdhanBuYm1wZXJ2VHRFZUU4d3dLcmk3cldwVXM9IiwiQyI6IjAyMTk1MDgxZTYyMmY5OGJmYzE5YTA1ZWJlMjM0MWQ5NTVjMGQxMjU4OGM1OTQ4Yzg1OGQwN2FkZWMwMDdiYzFlNCJ9XX1dfQ'; - - const obj = { - proofs: [ - { - id: 'I2yN+iRYfkzT', - amount: 1, - secret: '97zfmmaGf5k8Mg0gajpnbmpervTtEeE8wwKri7rWpUs=', - C: '02195081e622f98bfc19a05ebe2341d955c0d12588c5948c858d07adec007bc1e4' - } - ], - mints: [{ url: 'http://localhost:3338', ids: ['L3zxxRB/I8uE', 'I2yN+iRYfkzT'] }] - }; - - const result = utils.getEncodedToken({ - token: [{ mint: obj.mints[0].url, proofs: obj.proofs }] - }); - expect(result).toEqual(token); + let result: Token | undefined; + expect(() => { + result = utils.getDecodedToken(token); + }).toThrow(); + expect(result).toBe(undefined); }); }); @@ -176,10 +109,57 @@ describe('test decode token', () => { }; const token = - 'eyJ0b2tlbiI6W3sibWludCI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzMzOCIsInByb29mcyI6W3siaWQiOiJJMnlOK2lSWWZrelQiLCJhbW91bnQiOjEsInNlY3JldCI6Ijk3emZtbWFHZjVrOE1nMGdhanBuYm1wZXJ2VHRFZUU4d3dLcmk3cldwVXM9IiwiQyI6IjAyMTk1MDgxZTYyMmY5OGJmYzE5YTA1ZWJlMjM0MWQ5NTVjMGQxMjU4OGM1OTQ4Yzg1OGQwN2FkZWMwMDdiYzFlNCJ9XX1dfQ'; + 'AeyJ0b2tlbiI6W3sibWludCI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzMzOCIsInByb29mcyI6W3siaWQiOiJJMnlOK2lSWWZrelQiLCJhbW91bnQiOjEsInNlY3JldCI6Ijk3emZtbWFHZjVrOE1nMGdhanBuYm1wZXJ2VHRFZUU4d3dLcmk3cldwVXM9IiwiQyI6IjAyMTk1MDgxZTYyMmY5OGJmYzE5YTA1ZWJlMjM0MWQ5NTVjMGQxMjU4OGM1OTQ4Yzg1OGQwN2FkZWMwMDdiYzFlNCJ9XX1dfQ'; const result = utils.getDecodedToken(token); expect(result).toStrictEqual(obj); }); + test('testing v4 Token', () => { + const v3Token = { + memo: '', + token: [ + { + mint: 'https://mint.minibits.cash/Bitcoin', + proofs: [ + { + secret: '7e98535c6f8cd7a5eff150963a2743613a91e9498150fd5af8d2bfcfd5babe68', + C: '03022a28d163cf63792c1533e6660112f2b75db2fe46aa840e7f5d0f979a2c6cfd', + id: '00500550f0494146', + amount: 16 + }, + { + amount: 4, + secret: '96bd8480717673311bc70e92818b5babcb665edee39b639defad5584d8d18b1f', + C: '030936759e03235867f9cea58f047c043acdd7455f604c92c75839e5e08a91e198', + id: '00500550f0494146' + }, + { + secret: 'e145fa7fba21a9cd3c8743c9de5e4de33e0095abc50b262f1b3831b69b8f63df', + id: '00500550f0494146', + C: '03eba391a31e101e1ba1853db1e4bbb6a166d4fbbb1e181e82892c3301e4e02015', + amount: 1 + } + ] + } + ] + }; + + const token = + 'cashuBuQACYXSBuQACYXCDuQADYWEQYXN4QDdlOTg1MzVjNmY4Y2Q3YTVlZmYxNTA5NjNhMjc0MzYxM2E5MWU5NDk4MTUwZmQ1YWY4ZDJiZmNmZDViYWJlNjhhY3hCMDMwMjJhMjhkMTYzY2Y2Mzc5MmMxNTMzZTY2NjAxMTJmMmI3NWRiMmZlNDZhYTg0MGU3ZjVkMGY5NzlhMmM2Y2ZkuQADYWEEYXN4QDk2YmQ4NDgwNzE3NjczMzExYmM3MGU5MjgxOGI1YmFiY2I2NjVlZGVlMzliNjM5ZGVmYWQ1NTg0ZDhkMThiMWZhY3hCMDMwOTM2NzU5ZTAzMjM1ODY3ZjljZWE1OGYwNDdjMDQzYWNkZDc0NTVmNjA0YzkyYzc1ODM5ZTVlMDhhOTFlMTk4uQADYWEBYXN4QGUxNDVmYTdmYmEyMWE5Y2QzYzg3NDNjOWRlNWU0ZGUzM2UwMDk1YWJjNTBiMjYyZjFiMzgzMWI2OWI4ZjYzZGZhY3hCMDNlYmEzOTFhMzFlMTAxZTFiYTE4NTNkYjFlNGJiYjZhMTY2ZDRmYmJiMWUxODFlODI4OTJjMzMwMWU0ZTAyMDE1YWlwMDA1MDA1NTBmMDQ5NDE0NmFteCJodHRwczovL21pbnQubWluaWJpdHMuY2FzaC9CaXRjb2lu'; + + const result = utils.getDecodedToken(token); + console.log(JSON.stringify(result)); + expect(result).toStrictEqual(v3Token); + }); + test('testing joining urls', () => { + const mint_url = 'http://localhost:3338'; + const info_url = utils.joinUrls(mint_url, 'info'); + + expect(info_url).toBe('http://localhost:3338/info'); + + const mint_url_trailing_slash = 'http://localhost:3338/'; + const mint_info_url = utils.joinUrls(mint_url_trailing_slash, 'info'); + expect(mint_info_url).toBe('http://localhost:3338/info'); + }); }); describe('test keyset derivation', () => { From f77485f49d7da69bb7ee79d1348dd421bb9e382f Mon Sep 17 00:00:00 2001 From: Egge Date: Fri, 28 Jun 2024 11:22:49 +0200 Subject: [PATCH 02/39] added cbor-x --- package-lock.json | 2747 +++++++++++++++++++++++---------------------- package.json | 3 +- 2 files changed, 1433 insertions(+), 1317 deletions(-) diff --git a/package-lock.json b/package-lock.json index 59723872d..679480b7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,8 @@ "@noble/hashes": "^1.3.3", "@scure/bip32": "^1.3.3", "@scure/bip39": "^1.2.2", - "buffer": "^6.0.3" + "buffer": "^6.0.3", + "cbor-x": "^1.5.9" }, "devDependencies": { "@types/jest": "^29.5.1", @@ -51,119 +52,48 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/compat-data": { - "version": "7.20.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", - "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.7.tgz", - "integrity": "sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.7", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7", - "convert-source-map": "^1.7.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -173,21 +103,15 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", "dev": true, "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -195,186 +119,188 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dev": true, "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, "dependencies": { - "@babel/types": "^7.20.2" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", - "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -452,9 +378,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -524,12 +450,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", - "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -626,12 +552,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", - "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -641,33 +567,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", - "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.6", - "@babel/types": "^7.23.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -676,13 +602,13 @@ } }, "node_modules/@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -707,6 +633,78 @@ "buffer": "^6.0.3" } }, + "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", + "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@cbor-extract/cbor-extract-darwin-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", + "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-arm": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", + "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", + "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", + "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-win32-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", + "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -889,16 +887,16 @@ } }, "node_modules/@jest/console": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", - "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" }, "engines": { @@ -906,37 +904,37 @@ } }, "node_modules/@jest/core": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", - "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, "dependencies": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -953,89 +951,89 @@ } }, "node_modules/@jest/environment": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", - "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0" + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, "dependencies": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", - "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, "dependencies": { - "jest-get-type": "^29.4.3" + "jest-get-type": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", - "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", - "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", - "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -1043,13 +1041,13 @@ "glob": "^7.1.3", "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -1067,25 +1065,53 @@ } } }, + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", + "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.25.16" + "@sinclair/typebox": "^0.27.8" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/source-map": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", - "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", + "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" }, @@ -1094,13 +1120,13 @@ } }, "node_modules/@jest/test-result": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", - "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, "dependencies": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1109,14 +1135,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", - "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, "dependencies": { - "@jest/test-result": "^29.5.0", + "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.7.0", "slash": "^3.0.0" }, "engines": { @@ -1124,22 +1150,22 @@ } }, "node_modules/@jest/transform": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", - "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -1150,12 +1176,12 @@ } }, "node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1189,9 +1215,9 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" @@ -1204,13 +1230,13 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@noble/curves": { @@ -1304,27 +1330,27 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, "node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "dependencies": { - "@sinonjs/commons": "^2.0.0" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@tsconfig/node10": { @@ -1352,9 +1378,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", - "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "dependencies": { "@babel/parser": "^7.20.7", @@ -1365,18 +1391,18 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -1384,12 +1410,12 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", - "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, "dependencies": { - "@babel/types": "^7.3.0" + "@babel/types": "^7.20.7" } }, "node_modules/@types/graceful-fs": { @@ -1463,12 +1489,6 @@ "form-data": "^3.0.0" } }, - "node_modules/@types/prettier": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", - "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", - "dev": true - }, "node_modules/@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", @@ -1973,15 +1993,15 @@ "dev": true }, "node_modules/babel-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", - "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "dependencies": { - "@jest/transform": "^29.5.0", + "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", + "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -2010,9 +2030,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", - "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -2048,12 +2068,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", - "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^29.5.0", + "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -2112,9 +2132,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", "dev": true, "funding": [ { @@ -2124,13 +2144,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" }, "bin": { "browserslist": "cli.js" @@ -2263,9 +2287,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001441", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", - "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", + "version": "1.0.30001638", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz", + "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==", "dev": true, "funding": [ { @@ -2275,9 +2299,42 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, + "node_modules/cbor-extract": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", + "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.1.1" + }, + "bin": { + "download-cbor-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", + "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", + "@cbor-extract/cbor-extract-linux-x64": "2.2.0", + "@cbor-extract/cbor-extract-win32-x64": "2.2.0" + } + }, + "node_modules/cbor-x": { + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.5.9.tgz", + "integrity": "sha512-OEI5rEu3MeR0WWNUXuIGkxmbXVhABP+VtgAXzm48c9ulkrsvxshjjk94XSOGphyAKeNGLPfAxxzEtgQ6rEVpYQ==", + "optionalDependencies": { + "cbor-extract": "^2.2.0" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2313,9 +2370,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", "dev": true }, "node_modules/cliui": { @@ -2343,9 +2400,9 @@ } }, "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, "node_modules/color-convert": { @@ -2390,6 +2447,27 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -2428,10 +2506,18 @@ } }, "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, "node_modules/deep-is": { "version": "0.1.4", @@ -2473,6 +2559,15 @@ "node": ">=0.4.0" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -2492,9 +2587,9 @@ } }, "node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -2525,9 +2620,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "version": "1.4.814", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.814.tgz", + "integrity": "sha512-GVulpHjFu1Y9ZvikvbArHmAhZXtm3wHlpjTMcXNGKl4IQ4jMQjlnz8yMQYYqdLHKi/jEL2+CBC2akWVCoIGUdw==", "dev": true }, "node_modules/emittery": { @@ -2623,9 +2718,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -3253,16 +3348,16 @@ } }, "node_modules/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4077,17 +4172,17 @@ } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps": { @@ -4105,9 +4200,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -4118,15 +4213,15 @@ } }, "node_modules/jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "dependencies": { - "@jest/core": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^29.5.0" + "jest-cli": "^29.7.0" }, "bin": { "jest": "bin/jest.js" @@ -4144,12 +4239,13 @@ } }, "node_modules/jest-changed-files": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", - "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, "dependencies": { "execa": "^5.0.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0" }, "engines": { @@ -4157,28 +4253,28 @@ } }, "node_modules/jest-circus": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", - "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^0.7.0", + "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" @@ -4188,22 +4284,21 @@ } }, "node_modules/jest-cli": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", - "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, "dependencies": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", + "create-jest": "^29.7.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "prompts": "^2.0.1", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "yargs": "^17.3.1" }, "bin": { @@ -4222,31 +4317,31 @@ } }, "node_modules/jest-config": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", - "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.5.0", - "jest-environment-node": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -4267,24 +4362,24 @@ } }, "node_modules/jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-docblock": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", - "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, "dependencies": { "detect-newline": "^3.0.0" @@ -4294,62 +4389,62 @@ } }, "node_modules/jest-each": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", - "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-node": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", - "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -4361,46 +4456,46 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", - "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, "dependencies": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4409,14 +4504,14 @@ } }, "node_modules/jest-mock": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", - "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.5.0" + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4440,26 +4535,26 @@ } }, "node_modules/jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", - "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.7.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -4469,43 +4564,43 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", - "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, "dependencies": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", - "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, "dependencies": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -4514,31 +4609,31 @@ } }, "node_modules/jest-runtime": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", - "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -4547,59 +4642,41 @@ } }, "node_modules/jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.5.0", + "expect": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -4607,19 +4684,13 @@ "node": ">=10" } }, - "node_modules/jest-snapshot/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -4631,17 +4702,17 @@ } }, "node_modules/jest-validate": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", - "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", + "jest-get-type": "^29.6.3", "leven": "^3.1.0", - "pretty-format": "^29.5.0" + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4660,18 +4731,18 @@ } }, "node_modules/jest-watcher": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", - "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, "dependencies": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.5.0", + "jest-util": "^29.7.0", "string-length": "^4.0.1" }, "engines": { @@ -4679,13 +4750,13 @@ } }, "node_modules/jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, "dependencies": { "@types/node": "*", - "jest-util": "^29.5.0", + "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -4874,20 +4945,32 @@ "dev": true }, "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -5047,6 +5130,20 @@ } } }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -5054,9 +5151,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node_modules/normalize-path": { @@ -5298,9 +5395,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "node_modules/picomatch": { @@ -5361,12 +5458,12 @@ } }, "node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -5418,9 +5515,9 @@ } }, "node_modules/pure-rand": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", - "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, "funding": [ { @@ -6184,9 +6281,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "dev": true, "funding": [ { @@ -6196,14 +6293,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -6225,25 +6326,19 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", - "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" + "convert-source-map": "^2.0.0" }, "engines": { "node": ">=10.12.0" } }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, "node_modules/vscode-oniguruma": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", @@ -6373,9 +6468,9 @@ "dev": true }, "node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { "cliui": "^8.0.1", @@ -6433,260 +6528,196 @@ } }, "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" } }, "@babel/compat-data": { - "version": "7.20.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", - "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", "dev": true }, "@babel/core": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.7.tgz", - "integrity": "sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.7", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7", - "convert-source-map": "^1.7.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "dependencies": { - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - } + "json5": "^2.2.3", + "semver": "^6.3.1" } }, "@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", "dev": true, "requires": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } } } }, "@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", "dev": true, "requires": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" } }, "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "requires": { + "@babel/types": "^7.24.7" + } }, "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dev": true, "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" } }, "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" } }, "@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", "dev": true }, "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, "requires": { - "@babel/types": "^7.20.2" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" } }, "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", "dev": true }, "@babel/helpers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", - "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", "dev": true, "requires": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "dependencies": { "ansi-styles": { @@ -6748,9 +6779,9 @@ } }, "@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -6799,12 +6830,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", - "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -6871,51 +6902,51 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", - "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/traverse": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", - "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.6", - "@babel/types": "^7.23.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", "debug": "^4.3.1", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" } }, @@ -6937,6 +6968,42 @@ "buffer": "^6.0.3" } }, + "@cbor-extract/cbor-extract-darwin-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", + "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", + "optional": true + }, + "@cbor-extract/cbor-extract-darwin-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", + "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", + "optional": true + }, + "@cbor-extract/cbor-extract-linux-arm": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", + "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", + "optional": true + }, + "@cbor-extract/cbor-extract-linux-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", + "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", + "optional": true + }, + "@cbor-extract/cbor-extract-linux-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", + "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", + "optional": true + }, + "@cbor-extract/cbor-extract-win32-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", + "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", + "optional": true + }, "@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -7071,124 +7138,124 @@ "dev": true }, "@jest/console": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", - "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, "requires": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" } }, "@jest/core": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", - "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, "requires": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" } }, "@jest/environment": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", - "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, "requires": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0" + "jest-mock": "^29.7.0" } }, "@jest/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, "requires": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" } }, "@jest/expect-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", - "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, "requires": { - "jest-get-type": "^29.4.3" + "jest-get-type": "^29.6.3" } }, "@jest/fake-timers": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", - "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, "requires": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" } }, "@jest/globals": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", - "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, "requires": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" } }, "@jest/reporters": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", - "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -7196,80 +7263,101 @@ "glob": "^7.1.3", "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", "v8-to-istanbul": "^9.0.1" + }, + "dependencies": { + "istanbul-lib-instrument": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", + "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "dev": true, + "requires": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + } + }, + "semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true + } } }, "@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "requires": { - "@sinclair/typebox": "^0.25.16" + "@sinclair/typebox": "^0.27.8" } }, "@jest/source-map": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", - "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.15", + "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" } }, "@jest/test-result": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", - "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, "requires": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", - "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, "requires": { - "@jest/test-result": "^29.5.0", + "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.7.0", "slash": "^3.0.0" } }, "@jest/transform": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", - "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -7277,12 +7365,12 @@ } }, "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, "requires": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -7307,9 +7395,9 @@ "dev": true }, "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true }, "@jridgewell/sourcemap-codec": { @@ -7319,13 +7407,13 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@noble/curves": { @@ -7392,27 +7480,27 @@ } }, "@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "requires": { "type-detect": "4.0.8" } }, "@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "requires": { - "@sinonjs/commons": "^2.0.0" + "@sinonjs/commons": "^3.0.0" } }, "@tsconfig/node10": { @@ -7440,9 +7528,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", - "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "requires": { "@babel/parser": "^7.20.7", @@ -7453,18 +7541,18 @@ } }, "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -7472,12 +7560,12 @@ } }, "@types/babel__traverse": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", - "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, "requires": { - "@babel/types": "^7.3.0" + "@babel/types": "^7.20.7" } }, "@types/graceful-fs": { @@ -7551,12 +7639,6 @@ "form-data": "^3.0.0" } }, - "@types/prettier": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", - "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", - "dev": true - }, "@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", @@ -7897,15 +7979,15 @@ "dev": true }, "babel-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", - "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "requires": { - "@jest/transform": "^29.5.0", + "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", + "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -7925,9 +8007,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", - "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -7957,12 +8039,12 @@ } }, "babel-preset-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", - "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^29.5.0", + "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -7997,15 +8079,15 @@ } }, "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" } }, "bs-logger": { @@ -8099,11 +8181,34 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001441", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", - "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", + "version": "1.0.30001638", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz", + "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==", "dev": true }, + "cbor-extract": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", + "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", + "optional": true, + "requires": { + "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", + "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", + "@cbor-extract/cbor-extract-linux-x64": "2.2.0", + "@cbor-extract/cbor-extract-win32-x64": "2.2.0", + "node-gyp-build-optional-packages": "5.1.1" + } + }, + "cbor-x": { + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.5.9.tgz", + "integrity": "sha512-OEI5rEu3MeR0WWNUXuIGkxmbXVhABP+VtgAXzm48c9ulkrsvxshjjk94XSOGphyAKeNGLPfAxxzEtgQ6rEVpYQ==", + "requires": { + "cbor-extract": "^2.2.0" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -8127,9 +8232,9 @@ "dev": true }, "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", "dev": true }, "cliui": { @@ -8150,9 +8255,9 @@ "dev": true }, "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, "color-convert": { @@ -8191,6 +8296,21 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + } + }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -8218,10 +8338,11 @@ } }, "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "requires": {} }, "deep-is": { "version": "0.1.4", @@ -8251,6 +8372,12 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, + "detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "optional": true + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -8264,9 +8391,9 @@ "dev": true }, "diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true }, "dir-glob": { @@ -8288,9 +8415,9 @@ } }, "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "version": "1.4.814", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.814.tgz", + "integrity": "sha512-GVulpHjFu1Y9ZvikvbArHmAhZXtm3wHlpjTMcXNGKl4IQ4jMQjlnz8yMQYYqdLHKi/jEL2+CBC2akWVCoIGUdw==", "dev": true }, "emittery": { @@ -8368,9 +8495,9 @@ } }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true }, "escape-string-regexp": { @@ -8807,16 +8934,16 @@ "dev": true }, "expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, "requires": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" } }, "fast-deep-equal": { @@ -9390,13 +9517,13 @@ } }, "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" } }, @@ -9412,9 +9539,9 @@ } }, "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -9422,227 +9549,227 @@ } }, "jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "requires": { - "@jest/core": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^29.5.0" + "jest-cli": "^29.7.0" } }, "jest-changed-files": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", - "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, "requires": { "execa": "^5.0.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0" } }, "jest-circus": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", - "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, "requires": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^0.7.0", + "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-cli": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", - "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, "requires": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", + "create-jest": "^29.7.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "prompts": "^2.0.1", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "yargs": "^17.3.1" } }, "jest-config": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", - "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.5.0", - "jest-environment-node": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" } }, "jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" } }, "jest-docblock": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", - "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", - "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, "requires": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" } }, "jest-environment-node": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", - "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, "requires": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" } }, "jest-get-type": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true }, "jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, "requires": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-leak-detector": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", - "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, "requires": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" } }, "jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" } }, "jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", - "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, "requires": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.5.0" + "jest-util": "^29.7.0" } }, "jest-pnp-resolver": { @@ -9653,161 +9780,140 @@ "requires": {} }, "jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true }, "jest-resolve": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", - "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, "requires": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.7.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", - "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, "requires": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" } }, "jest-runner": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", - "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, "requires": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" } }, "jest-runtime": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", - "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" } }, "jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, "requires": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.5.0", + "expect": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true } } }, "jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, "requires": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -9816,17 +9922,17 @@ } }, "jest-validate": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", - "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "requires": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", + "jest-get-type": "^29.6.3", "leven": "^3.1.0", - "pretty-format": "^29.5.0" + "pretty-format": "^29.7.0" }, "dependencies": { "camelcase": { @@ -9838,29 +9944,29 @@ } }, "jest-watcher": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", - "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, "requires": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.5.0", + "jest-util": "^29.7.0", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, "requires": { "@types/node": "*", - "jest-util": "^29.5.0", + "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -10011,12 +10117,20 @@ "dev": true }, "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "requires": { - "semver": "^6.0.0" + "semver": "^7.5.3" + }, + "dependencies": { + "semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true + } } }, "make-error": { @@ -10137,6 +10251,15 @@ "whatwg-url": "^5.0.0" } }, + "node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "optional": true, + "requires": { + "detect-libc": "^2.0.1" + } + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -10144,9 +10267,9 @@ "dev": true }, "node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "normalize-path": { @@ -10318,9 +10441,9 @@ "dev": true }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "picomatch": { @@ -10357,12 +10480,12 @@ "dev": true }, "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "requires": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -10398,9 +10521,9 @@ "dev": true }, "pure-rand": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", - "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true }, "queue-microtask": { @@ -10915,13 +11038,13 @@ } }, "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "dev": true, "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" } }, "uri-js": { @@ -10940,22 +11063,14 @@ "dev": true }, "v8-to-istanbul": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", - "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - }, - "dependencies": { - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - } + "convert-source-map": "^2.0.0" } }, "vscode-oniguruma": { @@ -11063,9 +11178,9 @@ "dev": true }, "yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { "cliui": "^8.0.1", diff --git a/package.json b/package.json index 58980401e..0986aadc3 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@noble/hashes": "^1.3.3", "@scure/bip32": "^1.3.3", "@scure/bip39": "^1.2.2", - "buffer": "^6.0.3" + "buffer": "^6.0.3", + "cbor-x": "^1.5.9" } } From 96e7314871925d5115abe5544439839e67b721a9 Mon Sep 17 00:00:00 2001 From: Egge Date: Fri, 28 Jun 2024 11:23:08 +0200 Subject: [PATCH 03/39] added tokenv4 parsing / removed depracated token --- src/utils.ts | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 48a2a00cd..87dcf43b3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -81,9 +81,9 @@ function getEncodedToken(token: Token): string { * @param token an encoded cashu token (cashuAey...) * @returns cashu token object */ -function getDecodedToken(token: string): Token { +function getDecodedToken(token: string) { // remove prefixes - const uriPrefixes = ['web+cashu://', 'cashu://', 'cashu:', 'cashuA']; + const uriPrefixes = ['web+cashu://', 'cashu://', 'cashu:', 'cashu']; uriPrefixes.forEach((prefix) => { if (!token.startsWith(prefix)) { return; @@ -97,21 +97,29 @@ function getDecodedToken(token: string): Token { * @param token * @returns */ -function handleTokens(token: string): Token { - const obj = encodeBase64ToJson | Token>(token); - - // check if v3 - if ('token' in obj) { - return obj; - } - - // check if v1 - if (Array.isArray(obj)) { - return { token: [{ proofs: obj, mint: '' }] }; +function handleTokens(token: string): Token | undefined { + const version = token.slice(0, 1); + const encodedToken = token.slice(1); + if (version === 'A') { + return encodeBase64ToJson(encodedToken); + } else if (version === 'B') { + const uInt8Token = encodeBase64toUint8(encodedToken); + const tokenData = decode(uInt8Token) as { + t: { p: { a: number; s: string; c: string }[]; i: string }[]; + m: string; + }; + const tokenEntries = tokenData.t.map( + (tokenEntry): TokenEntry => ({ + mint: tokenData.m, + proofs: tokenEntry.p.map( + (p): Proof => ({ secret: p.s, C: p.c, amount: p.a, id: tokenEntry.i }) + ) + }) + ); + return { token: tokenEntries, memo: '' }; + } else { + throw new Error('Token version is not supported'); } - - // if v2 token return v3 format - return { token: [{ proofs: obj.proofs, mint: obj?.mints[0]?.url ?? '' }] }; } /** * Returns the keyset id of a set of keys From 9b5b42c09ef49917a0a586c04f3112fa067dc77c Mon Sep 17 00:00:00 2001 From: Egge Date: Sun, 30 Jun 2024 06:33:31 +0200 Subject: [PATCH 04/39] remove cbor dependency --- package-lock.json | 201 +----------------------------------------- package.json | 3 +- src/cbor.ts | 216 ++++++++++++++++++++++++++++++++++++++++++++++ src/utils.ts | 7 +- 4 files changed, 222 insertions(+), 205 deletions(-) create mode 100644 src/cbor.ts diff --git a/package-lock.json b/package-lock.json index 679480b7a..7ee763349 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,8 +14,7 @@ "@noble/hashes": "^1.3.3", "@scure/bip32": "^1.3.3", "@scure/bip39": "^1.2.2", - "buffer": "^6.0.3", - "cbor-x": "^1.5.9" + "buffer": "^6.0.3" }, "devDependencies": { "@types/jest": "^29.5.1", @@ -633,78 +632,6 @@ "buffer": "^6.0.3" } }, - "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", - "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@cbor-extract/cbor-extract-darwin-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", - "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-arm": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", - "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", - "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", - "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-win32-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", - "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -2306,35 +2233,6 @@ } ] }, - "node_modules/cbor-extract": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", - "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build-optional-packages": "5.1.1" - }, - "bin": { - "download-cbor-prebuilds": "bin/download-prebuilds.js" - }, - "optionalDependencies": { - "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", - "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", - "@cbor-extract/cbor-extract-linux-arm": "2.2.0", - "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", - "@cbor-extract/cbor-extract-linux-x64": "2.2.0", - "@cbor-extract/cbor-extract-win32-x64": "2.2.0" - } - }, - "node_modules/cbor-x": { - "version": "1.5.9", - "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.5.9.tgz", - "integrity": "sha512-OEI5rEu3MeR0WWNUXuIGkxmbXVhABP+VtgAXzm48c9ulkrsvxshjjk94XSOGphyAKeNGLPfAxxzEtgQ6rEVpYQ==", - "optionalDependencies": { - "cbor-extract": "^2.2.0" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2559,15 +2457,6 @@ "node": ">=0.4.0" } }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "optional": true, - "engines": { - "node": ">=8" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -5130,20 +5019,6 @@ } } }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", - "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", - "optional": true, - "dependencies": { - "detect-libc": "^2.0.1" - }, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -6968,42 +6843,6 @@ "buffer": "^6.0.3" } }, - "@cbor-extract/cbor-extract-darwin-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", - "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", - "optional": true - }, - "@cbor-extract/cbor-extract-darwin-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", - "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", - "optional": true - }, - "@cbor-extract/cbor-extract-linux-arm": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", - "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", - "optional": true - }, - "@cbor-extract/cbor-extract-linux-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", - "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", - "optional": true - }, - "@cbor-extract/cbor-extract-linux-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", - "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", - "optional": true - }, - "@cbor-extract/cbor-extract-win32-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", - "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", - "optional": true - }, "@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -8186,29 +8025,6 @@ "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==", "dev": true }, - "cbor-extract": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", - "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", - "optional": true, - "requires": { - "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", - "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", - "@cbor-extract/cbor-extract-linux-arm": "2.2.0", - "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", - "@cbor-extract/cbor-extract-linux-x64": "2.2.0", - "@cbor-extract/cbor-extract-win32-x64": "2.2.0", - "node-gyp-build-optional-packages": "5.1.1" - } - }, - "cbor-x": { - "version": "1.5.9", - "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.5.9.tgz", - "integrity": "sha512-OEI5rEu3MeR0WWNUXuIGkxmbXVhABP+VtgAXzm48c9ulkrsvxshjjk94XSOGphyAKeNGLPfAxxzEtgQ6rEVpYQ==", - "requires": { - "cbor-extract": "^2.2.0" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -8372,12 +8188,6 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, - "detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "optional": true - }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -10251,15 +10061,6 @@ "whatwg-url": "^5.0.0" } }, - "node-gyp-build-optional-packages": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", - "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", - "optional": true, - "requires": { - "detect-libc": "^2.0.1" - } - }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", diff --git a/package.json b/package.json index 0986aadc3..58980401e 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "@noble/hashes": "^1.3.3", "@scure/bip32": "^1.3.3", "@scure/bip39": "^1.2.2", - "buffer": "^6.0.3", - "cbor-x": "^1.5.9" + "buffer": "^6.0.3" } } diff --git a/src/cbor.ts b/src/cbor.ts new file mode 100644 index 000000000..a998caf2f --- /dev/null +++ b/src/cbor.ts @@ -0,0 +1,216 @@ +export function encodeCBOR(value: any) { + const buffer: Array = []; + encodeItem(value, buffer); + return new Uint8Array(buffer); +} + +function encodeItem(value: any, buffer: Array) { + if (value === null) { + buffer.push(0xf6); + } else if (value === undefined) { + buffer.push(0xf7); + } else if (typeof value === 'boolean') { + buffer.push(value ? 0xf5 : 0xf4); + } else if (typeof value === 'number') { + encodeUnsigned(value, buffer); + } else if (typeof value === 'string') { + encodeString(value, buffer); + } else if (Array.isArray(value)) { + encodeArray(value, buffer); + } else if (typeof value === 'object') { + encodeObject(value, buffer); + } else { + throw new Error('Unsupported type'); + } +} + +function encodeUnsigned(value: number, buffer: Array) { + if (value < 24) { + buffer.push(value); + } else if (value < 256) { + buffer.push(0x18, value); + } else if (value < 65536) { + buffer.push(0x19, value >> 8, value & 0xff); + } else if (value < 4294967296) { + buffer.push(0x1a, value >> 24, (value >> 16) & 0xff, (value >> 8) & 0xff, value & 0xff); + } else { + throw new Error('Unsupported integer size'); + } +} + +function encodeString(value: string, buffer: Array) { + const utf8 = new TextEncoder().encode(value); + encodeUnsigned(utf8.length, buffer); + buffer[buffer.length - 1] |= 0x60; + utf8.forEach((b) => buffer.push(b)); +} + +function encodeArray(value: Array, buffer: Array) { + encodeUnsigned(value.length, buffer); + buffer[buffer.length - 1] |= 0x80; + for (const item of value) { + encodeItem(item, buffer); + } +} + +function encodeObject(value: { [key: string]: any }, buffer: Array) { + const keys = Object.keys(value); + encodeUnsigned(keys.length, buffer); + buffer[buffer.length - 1] |= 0xa0; + for (const key of keys) { + encodeString(key, buffer); + encodeItem(value[key], buffer); + } +} +type DecodeResult = { + value: any; + offset: number; +}; + +export function decodeCBOR(data: Uint8Array): any { + const view = new DataView(data.buffer, data.byteOffset, data.byteLength); + const result = decodeItem(view, 0); + return result.value; +} + +function decodeItem(view: DataView, offset: number): DecodeResult { + if (offset >= view.byteLength) { + throw new Error('Unexpected end of data'); + } + const initialByte = view.getUint8(offset++); + const majorType = initialByte >> 5; + const additionalInfo = initialByte & 0x1f; + + switch (majorType) { + case 0: + return decodeUnsigned(view, offset, additionalInfo); + case 1: + return decodeSigned(view, offset, additionalInfo); + case 2: + return decodeByteString(view, offset, additionalInfo); + case 3: + return decodeString(view, offset, additionalInfo); + case 4: + return decodeArray(view, offset, additionalInfo); + case 5: + return decodeMap(view, offset, additionalInfo); + case 7: + return decodeSimpleAndFloat(view, offset, additionalInfo); + default: + throw new Error(`Unsupported major type: ${majorType}`); + } +} + +function decodeLength(view: DataView, offset: number, additionalInfo: number): DecodeResult { + if (additionalInfo < 24) return { value: additionalInfo, offset }; + if (additionalInfo === 24) return { value: view.getUint8(offset++), offset }; + if (additionalInfo === 25) { + const value = view.getUint16(offset, false); + offset += 2; + return { value, offset }; + } + if (additionalInfo === 26) { + const value = view.getUint32(offset, false); + offset += 4; + return { value, offset }; + } + if (additionalInfo === 27) { + const hi = view.getUint32(offset, false); + const lo = view.getUint32(offset + 4, false); + offset += 8; + return { value: hi * 2 ** 32 + lo, offset }; + } + throw new Error(`Unsupported length: ${additionalInfo}`); +} + +function decodeUnsigned(view: DataView, offset: number, additionalInfo: number): DecodeResult { + const { value, offset: newOffset } = decodeLength(view, offset, additionalInfo); + return { value, offset: newOffset }; +} + +function decodeSigned(view: DataView, offset: number, additionalInfo: number): DecodeResult { + const { value, offset: newOffset } = decodeLength(view, offset, additionalInfo); + return { value: -1 - value, offset: newOffset }; +} + +function decodeByteString(view: DataView, offset: number, additionalInfo: number): DecodeResult { + const { value: length, offset: newOffset } = decodeLength(view, offset, additionalInfo); + if (newOffset + length > view.byteLength) { + throw new Error('Byte string length exceeds data length'); + } + const value = new Uint8Array(view.buffer, view.byteOffset + newOffset, length); + return { value, offset: newOffset + length }; +} + +function decodeString(view: DataView, offset: number, additionalInfo: number): DecodeResult { + const { value: length, offset: newOffset } = decodeLength(view, offset, additionalInfo); + if (newOffset + length > view.byteLength) { + throw new Error('String length exceeds data length'); + } + const bytes = new Uint8Array(view.buffer, view.byteOffset + newOffset, length); + const value = new TextDecoder().decode(bytes); + return { value, offset: newOffset + length }; +} + +function decodeArray(view: DataView, offset: number, additionalInfo: number): DecodeResult { + const { value: length, offset: newOffset } = decodeLength(view, offset, additionalInfo); + const array = []; + let currentOffset = newOffset; + for (let i = 0; i < length; i++) { + const result = decodeItem(view, currentOffset); + array.push(result.value); + currentOffset = result.offset; + } + return { value: array, offset: currentOffset }; +} + +function decodeMap(view: DataView, offset: number, additionalInfo: number): DecodeResult { + const { value: length, offset: newOffset } = decodeLength(view, offset, additionalInfo); + const map: { [key: string]: any } = {}; + let currentOffset = newOffset; + for (let i = 0; i < length; i++) { + const keyResult = decodeItem(view, currentOffset); + const valueResult = decodeItem(view, keyResult.offset); + map[keyResult.value] = valueResult.value; + currentOffset = valueResult.offset; + } + return { value: map, offset: currentOffset }; +} + +function decodeSimpleAndFloat( + view: DataView, + offset: number, + additionalInfo: number +): DecodeResult { + if (additionalInfo < 24) { + switch (additionalInfo) { + case 20: + return { value: false, offset }; + case 21: + return { value: true, offset }; + case 22: + return { value: null, offset }; + case 23: + return { value: undefined, offset }; + default: + throw new Error(`Unknown simple value: ${additionalInfo}`); + } + } + if (additionalInfo === 24) return { value: view.getUint8(offset++), offset }; + if (additionalInfo === 25) { + const value = view.getUint16(offset, false); + offset += 2; + return { value, offset }; + } + if (additionalInfo === 26) { + const value = view.getFloat32(offset, false); + offset += 4; + return { value, offset }; + } + if (additionalInfo === 27) { + const value = view.getFloat64(offset, false); + offset += 8; + return { value, offset }; + } + throw new Error(`Unknown simple or float value: ${additionalInfo}`); +} diff --git a/src/utils.ts b/src/utils.ts index 87dcf43b3..5ffc70d81 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,8 +1,9 @@ -import { encodeBase64ToJson, encodeJsonToBase64 } from './base64.js'; -import { AmountPreference, Keys, Proof, Token, TokenV2 } from './model/types/index.js'; +import { encodeBase64ToJson, encodeBase64toUint8, encodeJsonToBase64 } from './base64.js'; +import { AmountPreference, Keys, Proof, Token, TokenEntry, TokenV2 } from './model/types/index.js'; import { TOKEN_PREFIX, TOKEN_VERSION } from './utils/Constants.js'; import { bytesToHex, hexToBytes } from '@noble/curves/abstract/utils'; import { sha256 } from '@noble/hashes/sha256'; +import { decodeCBOR } from './cbor.js'; function splitAmount(value: number, amountPreference?: Array): Array { const chunks: Array = []; @@ -104,7 +105,7 @@ function handleTokens(token: string): Token | undefined { return encodeBase64ToJson(encodedToken); } else if (version === 'B') { const uInt8Token = encodeBase64toUint8(encodedToken); - const tokenData = decode(uInt8Token) as { + const tokenData = decodeCBOR(uInt8Token) as { t: { p: { a: number; s: string; c: string }[]; i: string }[]; m: string; }; From ac2ae9db60524c67c3f7b1b4a88c9b137c3dbb4f Mon Sep 17 00:00:00 2001 From: Egge Date: Mon, 1 Jul 2024 10:16:35 +0200 Subject: [PATCH 05/39] added byte id and C --- src/utils.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 5ffc70d81..dfcd3479f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -106,14 +106,19 @@ function handleTokens(token: string): Token | undefined { } else if (version === 'B') { const uInt8Token = encodeBase64toUint8(encodedToken); const tokenData = decodeCBOR(uInt8Token) as { - t: { p: { a: number; s: string; c: string }[]; i: string }[]; + t: { p: { a: number; s: string; c: Uint8Array }[]; i: Uint8Array }[]; m: string; }; const tokenEntries = tokenData.t.map( (tokenEntry): TokenEntry => ({ mint: tokenData.m, proofs: tokenEntry.p.map( - (p): Proof => ({ secret: p.s, C: p.c, amount: p.a, id: tokenEntry.i }) + (p): Proof => ({ + secret: p.s, + C: bytesToHex(p.c), + amount: p.a, + id: bytesToHex(tokenEntry.i) + }) ) }) ); From bc3e8bd04b19dea8ec363f1e2d86aba5d1a011ed Mon Sep 17 00:00:00 2001 From: Egge Date: Mon, 1 Jul 2024 15:28:02 +0200 Subject: [PATCH 06/39] added testcases and multi token --- src/utils.ts | 23 ++++++++++----------- test/utils.test.ts | 51 +++++++++++++++++++++++++++++++++------------- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index dfcd3479f..842853028 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -108,21 +108,20 @@ function handleTokens(token: string): Token | undefined { const tokenData = decodeCBOR(uInt8Token) as { t: { p: { a: number; s: string; c: Uint8Array }[]; i: Uint8Array }[]; m: string; + d: string; }; - const tokenEntries = tokenData.t.map( - (tokenEntry): TokenEntry => ({ - mint: tokenData.m, - proofs: tokenEntry.p.map( - (p): Proof => ({ - secret: p.s, - C: bytesToHex(p.c), - amount: p.a, - id: bytesToHex(tokenEntry.i) - }) - ) + const mergedTokenEntry: TokenEntry = { mint: tokenData.m, proofs: [] }; + tokenData.t.forEach((tokenEntry) => + tokenEntry.p.forEach((p) => { + mergedTokenEntry.proofs.push({ + secret: p.s, + C: bytesToHex(p.c), + amount: p.a, + id: bytesToHex(tokenEntry.i) + }); }) ); - return { token: tokenEntries, memo: '' }; + return { token: [mergedTokenEntry], memo: tokenData.d || '' }; } else { throw new Error('Token version is not supported'); } diff --git a/test/utils.test.ts b/test/utils.test.ts index 15fa721aa..8e2117d5e 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -114,28 +114,52 @@ describe('test decode token', () => { expect(result).toStrictEqual(obj); }); test('testing v4 Token', () => { + const v3Token = { + memo: 'Thank you', + token: [ + { + mint: 'http://localhost:3338', + proofs: [ + { + secret: '9a6dbb847bd232ba76db0df197216b29d3b8cc14553cd27827fc1cc942fedb4e', + C: '038618543ffb6b8695df4ad4babcde92a34a96bdcd97dcee0d7ccf98d472126792', + id: '00ad268c4d1f5826', + amount: 1 + } + ] + } + ] + }; + + const token = + 'cashuBpGF0gaJhaUgArSaMTR9YJmFwgaNhYQFhc3hAOWE2ZGJiODQ3YmQyMzJiYTc2ZGIwZGYxOTcyMTZiMjlkM2I4Y2MxNDU1M2NkMjc4MjdmYzFjYzk0MmZlZGI0ZWFjWCEDhhhUP_trhpXfStS6vN6So0qWvc2X3O4NfM-Y1HISZ5JhZGlUaGFuayB5b3VhbXVodHRwOi8vbG9jYWxob3N0OjMzMzhhdWNzYXQ='; + + const result = utils.getDecodedToken(token); + expect(result).toStrictEqual(v3Token); + }); + test('testing v4 Token with multi keyset', () => { const v3Token = { memo: '', token: [ { - mint: 'https://mint.minibits.cash/Bitcoin', + mint: 'http://localhost:3338', proofs: [ { - secret: '7e98535c6f8cd7a5eff150963a2743613a91e9498150fd5af8d2bfcfd5babe68', - C: '03022a28d163cf63792c1533e6660112f2b75db2fe46aa840e7f5d0f979a2c6cfd', - id: '00500550f0494146', - amount: 16 + secret: 'acc12435e7b8484c3cf1850149218af90f716a52bf4a5ed347e48ecc13f77388', + C: '0244538319de485d55bed3b29a642bee5879375ab9e7a620e11e48ba482421f3cf', + id: '00ffd48b8f5ecf80', + amount: 1 }, { - amount: 4, - secret: '96bd8480717673311bc70e92818b5babcb665edee39b639defad5584d8d18b1f', - C: '030936759e03235867f9cea58f047c043acdd7455f604c92c75839e5e08a91e198', - id: '00500550f0494146' + secret: '1323d3d4707a58ad2e23ada4e9f1f49f5a5b4ac7b708eb0d61f738f48307e8ee', + C: '023456aa110d84b4ac747aebd82c3b005aca50bf457ebd5737a4414fac3ae7d94d', + id: '00ad268c4d1f5826', + amount: 2 }, { - secret: 'e145fa7fba21a9cd3c8743c9de5e4de33e0095abc50b262f1b3831b69b8f63df', - id: '00500550f0494146', - C: '03eba391a31e101e1ba1853db1e4bbb6a166d4fbbb1e181e82892c3301e4e02015', + secret: '56bcbcbb7cc6406b3fa5d57d2174f4eff8b4402b176926d3a57d3c3dcbb59d57', + C: '0273129c5719e599379a974a626363c333c56cafc0e6d01abe46d5808280789c63', + id: '00ad268c4d1f5826', amount: 1 } ] @@ -144,10 +168,9 @@ describe('test decode token', () => { }; const token = - 'cashuBuQACYXSBuQACYXCDuQADYWEQYXN4QDdlOTg1MzVjNmY4Y2Q3YTVlZmYxNTA5NjNhMjc0MzYxM2E5MWU5NDk4MTUwZmQ1YWY4ZDJiZmNmZDViYWJlNjhhY3hCMDMwMjJhMjhkMTYzY2Y2Mzc5MmMxNTMzZTY2NjAxMTJmMmI3NWRiMmZlNDZhYTg0MGU3ZjVkMGY5NzlhMmM2Y2ZkuQADYWEEYXN4QDk2YmQ4NDgwNzE3NjczMzExYmM3MGU5MjgxOGI1YmFiY2I2NjVlZGVlMzliNjM5ZGVmYWQ1NTg0ZDhkMThiMWZhY3hCMDMwOTM2NzU5ZTAzMjM1ODY3ZjljZWE1OGYwNDdjMDQzYWNkZDc0NTVmNjA0YzkyYzc1ODM5ZTVlMDhhOTFlMTk4uQADYWEBYXN4QGUxNDVmYTdmYmEyMWE5Y2QzYzg3NDNjOWRlNWU0ZGUzM2UwMDk1YWJjNTBiMjYyZjFiMzgzMWI2OWI4ZjYzZGZhY3hCMDNlYmEzOTFhMzFlMTAxZTFiYTE4NTNkYjFlNGJiYjZhMTY2ZDRmYmJiMWUxODFlODI4OTJjMzMwMWU0ZTAyMDE1YWlwMDA1MDA1NTBmMDQ5NDE0NmFteCJodHRwczovL21pbnQubWluaWJpdHMuY2FzaC9CaXRjb2lu'; + 'cashuBo2F0gqJhaUgA_9SLj17PgGFwgaNhYQFhc3hAYWNjMTI0MzVlN2I4NDg0YzNjZjE4NTAxNDkyMThhZjkwZjcxNmE1MmJmNGE1ZWQzNDdlNDhlY2MxM2Y3NzM4OGFjWCECRFODGd5IXVW-07KaZCvuWHk3WrnnpiDhHki6SCQh88-iYWlIAK0mjE0fWCZhcIKjYWECYXN4QDEzMjNkM2Q0NzA3YTU4YWQyZTIzYWRhNGU5ZjFmNDlmNWE1YjRhYzdiNzA4ZWIwZDYxZjczOGY0ODMwN2U4ZWVhY1ghAjRWqhENhLSsdHrr2Cw7AFrKUL9Ffr1XN6RBT6w659lNo2FhAWFzeEA1NmJjYmNiYjdjYzY0MDZiM2ZhNWQ1N2QyMTc0ZjRlZmY4YjQ0MDJiMTc2OTI2ZDNhNTdkM2MzZGNiYjU5ZDU3YWNYIQJzEpxXGeWZN5qXSmJjY8MzxWyvwObQGr5G1YCCgHicY2FtdWh0dHA6Ly9sb2NhbGhvc3Q6MzMzOGF1Y3NhdA=='; const result = utils.getDecodedToken(token); - console.log(JSON.stringify(result)); expect(result).toStrictEqual(v3Token); }); test('testing joining urls', () => { From 02bfb6423ba395ed99de80644dbdaa3f587f44f9 Mon Sep 17 00:00:00 2001 From: Egge Date: Mon, 1 Jul 2024 18:40:22 +0200 Subject: [PATCH 07/39] specified return type --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 842853028..1ace779b7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -98,7 +98,7 @@ function getDecodedToken(token: string) { * @param token * @returns */ -function handleTokens(token: string): Token | undefined { +function handleTokens(token: string): Token { const version = token.slice(0, 1); const encodedToken = token.slice(1); if (version === 'A') { From ca3595633cd18a37b954de3e27e43dc949eafcf6 Mon Sep 17 00:00:00 2001 From: Egge Date: Thu, 4 Jul 2024 10:57:57 +0200 Subject: [PATCH 08/39] cleanup rebase --- test/utils.test.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/utils.test.ts b/test/utils.test.ts index 8e2117d5e..1569cd782 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -173,16 +173,6 @@ describe('test decode token', () => { const result = utils.getDecodedToken(token); expect(result).toStrictEqual(v3Token); }); - test('testing joining urls', () => { - const mint_url = 'http://localhost:3338'; - const info_url = utils.joinUrls(mint_url, 'info'); - - expect(info_url).toBe('http://localhost:3338/info'); - - const mint_url_trailing_slash = 'http://localhost:3338/'; - const mint_info_url = utils.joinUrls(mint_url_trailing_slash, 'info'); - expect(mint_info_url).toBe('http://localhost:3338/info'); - }); }); describe('test keyset derivation', () => { From 717bdfc357ff1f49b40fc7ec4bb79c4ef7964850 Mon Sep 17 00:00:00 2001 From: Egge Date: Thu, 18 Jul 2024 16:08:52 +0200 Subject: [PATCH 09/39] added cbor test cases --- test/cbor.test.ts | 294 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 test/cbor.test.ts diff --git a/test/cbor.test.ts b/test/cbor.test.ts new file mode 100644 index 000000000..e9df53b1c --- /dev/null +++ b/test/cbor.test.ts @@ -0,0 +1,294 @@ +import { decodeCBOR } from '../src/cbor'; + +const tests = [ + { + cbor: 'AA==', + hex: '00', + roundtrip: true, + decoded: 0 + }, + { + cbor: 'AQ==', + hex: '01', + roundtrip: true, + decoded: 1 + }, + { + cbor: 'Cg==', + hex: '0a', + roundtrip: true, + decoded: 10 + }, + { + cbor: 'Fw==', + hex: '17', + roundtrip: true, + decoded: 23 + }, + { + cbor: 'GBg=', + hex: '1818', + roundtrip: true, + decoded: 24 + }, + { + cbor: 'GBk=', + hex: '1819', + roundtrip: true, + decoded: 25 + }, + { + cbor: 'GGQ=', + hex: '1864', + roundtrip: true, + decoded: 100 + }, + { + cbor: 'GQPo', + hex: '1903e8', + roundtrip: true, + decoded: 1000 + }, + { + cbor: 'GgAPQkA=', + hex: '1a000f4240', + roundtrip: true, + decoded: 1000000 + }, + { + cbor: 'GwAAAOjUpRAA', + hex: '1b000000e8d4a51000', + roundtrip: true, + decoded: 1000000000000 + }, + { + cbor: 'IA==', + hex: '20', + roundtrip: true, + decoded: -1 + }, + { + cbor: 'KQ==', + hex: '29', + roundtrip: true, + decoded: -10 + }, + { + cbor: 'OGM=', + hex: '3863', + roundtrip: true, + decoded: -100 + }, + { + cbor: 'OQPn', + hex: '3903e7', + roundtrip: true, + decoded: -1000 + }, + { + cbor: '+QAA', + hex: 'f90000', + roundtrip: true, + decoded: 0.0 + }, + { + cbor: '+TwA', + hex: 'f93c00', + roundtrip: true, + decoded: 1.0 + }, + { + cbor: '+z/xmZmZmZma', + hex: 'fb3ff199999999999a', + roundtrip: true, + decoded: 1.1 + }, + { + cbor: '+T4A', + hex: 'f93e00', + roundtrip: true, + decoded: 1.5 + }, + { + cbor: '+Xv/', + hex: 'f97bff', + roundtrip: true, + decoded: 65504.0 + }, + { + cbor: '+kfDUAA=', + hex: 'fa47c35000', + roundtrip: true, + decoded: 100000.0 + }, + { + cbor: '+n9///8=', + hex: 'fa7f7fffff', + roundtrip: true, + decoded: 3.4028234663852886e38 + }, + { + cbor: '+3435DyIAHWc', + hex: 'fb7e37e43c8800759c', + roundtrip: true, + decoded: 1.0e300 + }, + { + cbor: '+QAB', + hex: 'f90001', + roundtrip: true, + decoded: 5.960464477539063e-8 + }, + { + cbor: '+QQA', + hex: 'f90400', + roundtrip: true, + decoded: 6.103515625e-5 + }, + { + cbor: '+cQA', + hex: 'f9c400', + roundtrip: true, + decoded: -4.0 + }, + { + cbor: '+8AQZmZmZmZm', + hex: 'fbc010666666666666', + roundtrip: true, + decoded: -4.1 + }, + { + cbor: '9A==', + hex: 'f4', + roundtrip: true, + decoded: false + }, + { + cbor: '9Q==', + hex: 'f5', + roundtrip: true, + decoded: true + }, + { + cbor: '9g==', + hex: 'f6', + roundtrip: true, + decoded: null + }, + { + cbor: 'YA==', + hex: '60', + roundtrip: true, + decoded: '' + }, + { + cbor: 'YWE=', + hex: '6161', + roundtrip: true, + decoded: 'a' + }, + { + cbor: 'ZElFVEY=', + hex: '6449455446', + roundtrip: true, + decoded: 'IETF' + }, + { + cbor: 'YiJc', + hex: '62225c', + roundtrip: true, + decoded: '"\\' + }, + { + cbor: 'YsO8', + hex: '62c3bc', + roundtrip: true, + decoded: 'ü' + }, + { + cbor: 'Y+awtA==', + hex: '63e6b0b4', + roundtrip: true, + decoded: '水' + }, + { + cbor: 'ZPCQhZE=', + hex: '64f0908591', + roundtrip: true, + decoded: '𐅑' + }, + { + cbor: 'gA==', + hex: '80', + roundtrip: true, + decoded: [] + }, + { + cbor: 'gwECAw==', + hex: '83010203', + roundtrip: true, + decoded: [1, 2, 3] + }, + { + cbor: 'gwGCAgOCBAU=', + hex: '8301820203820405', + roundtrip: true, + decoded: [1, [2, 3], [4, 5]] + }, + { + cbor: 'mBkBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgYGBk=', + hex: '98190102030405060708090a0b0c0d0e0f101112131415161718181819', + roundtrip: true, + decoded: [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 + ] + }, + { + cbor: 'oA==', + hex: 'a0', + roundtrip: true, + decoded: {} + }, + { + cbor: 'omFhAWFiggID', + hex: 'a26161016162820203', + roundtrip: true, + decoded: { + a: 1, + b: [2, 3] + } + }, + { + cbor: 'gmFhoWFiYWM=', + hex: '826161a161626163', + roundtrip: true, + decoded: [ + 'a', + { + b: 'c' + } + ] + }, + { + cbor: 'pWFhYUFhYmFCYWNhQ2FkYURhZWFF', + hex: 'a56161614161626142616361436164614461656145', + roundtrip: true, + decoded: { + a: 'A', + b: 'B', + c: 'C', + d: 'D', + e: 'E' + } + } +]; + +describe('cbor decoder', () => { + test.each(tests)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { + //@ts-ignore + const res = decodeCBOR(Buffer.from(hex, 'hex')); + console.log(decoded); + console.log(res); + expect(res).toEqual(decoded); + }); +}); From ea96efed9bf7d46c1034997a8598afc103110f69 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:06:28 +0200 Subject: [PATCH 10/39] update nutshell docker image to 0.16.0 --- .github/workflows/nutshell-integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nutshell-integration.yml b/.github/workflows/nutshell-integration.yml index 8dafd40be..94ccf849e 100644 --- a/.github/workflows/nutshell-integration.yml +++ b/.github/workflows/nutshell-integration.yml @@ -8,7 +8,7 @@ jobs: steps: - name: Pull and start mint run: | - docker run -d -p 3338:3338 --name nutshell -e MINT_LIGHTNING_BACKEND=FakeWallet -e MINT_LISTEN_HOST=0.0.0.0 -e MINT_LISTEN_PORT=3338 -e MINT_PRIVATE_KEY=TEST_PRIVATE_KEY cashubtc/nutshell:0.15.2 poetry run mint + docker run -d -p 3338:3338 --name nutshell -e MINT_LIGHTNING_BACKEND=FakeWallet -e MINT_LISTEN_HOST=0.0.0.0 -e MINT_LISTEN_PORT=3338 -e MINT_PRIVATE_KEY=TEST_PRIVATE_KEY cashubtc/nutshell:0.16.0 poetry run mint - name: Check running containers run: docker ps From 1a3c4e52ad42daf75c2ca0d85a3350c3e4f15b21 Mon Sep 17 00:00:00 2001 From: Egge Date: Thu, 18 Jul 2024 16:09:05 +0200 Subject: [PATCH 11/39] fixed 16 bit float parsing --- src/cbor.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/cbor.ts b/src/cbor.ts index a998caf2f..4a78889c5 100644 --- a/src/cbor.ts +++ b/src/cbor.ts @@ -177,6 +177,19 @@ function decodeMap(view: DataView, offset: number, additionalInfo: number): Deco return { value: map, offset: currentOffset }; } +function decodeFloat16(uint16: number): number { + const exponent = (uint16 & 0x7c00) >> 10; + const fraction = uint16 & 0x03ff; + const sign = uint16 & 0x8000 ? -1 : 1; + + if (exponent === 0) { + return sign * 2 ** -14 * (fraction / 1024); + } else if (exponent === 0x1f) { + return fraction ? NaN : sign * Infinity; + } + return sign * 2 ** (exponent - 15) * (1 + fraction / 1024); +} + function decodeSimpleAndFloat( view: DataView, offset: number, @@ -198,7 +211,7 @@ function decodeSimpleAndFloat( } if (additionalInfo === 24) return { value: view.getUint8(offset++), offset }; if (additionalInfo === 25) { - const value = view.getUint16(offset, false); + const value = decodeFloat16(view.getUint16(offset, false)); offset += 2; return { value, offset }; } From f551ddcc180c8f0f4a92e2beac1e336c58def1bb Mon Sep 17 00:00:00 2001 From: Egge Date: Thu, 25 Jul 2024 14:22:44 +0200 Subject: [PATCH 12/39] adjusted tests --- test/cbor.test.ts | 154 ++++++++++++++-------------------------------- 1 file changed, 47 insertions(+), 107 deletions(-) diff --git a/test/cbor.test.ts b/test/cbor.test.ts index e9df53b1c..ada2df241 100644 --- a/test/cbor.test.ts +++ b/test/cbor.test.ts @@ -1,4 +1,5 @@ -import { decodeCBOR } from '../src/cbor'; +import { decodeCBOR, encodeCBOR } from '../src/cbor'; +import { bytesToHex, hexToBytes } from '@noble/curves/abstract/utils'; const tests = [ { @@ -55,108 +56,6 @@ const tests = [ roundtrip: true, decoded: 1000000 }, - { - cbor: 'GwAAAOjUpRAA', - hex: '1b000000e8d4a51000', - roundtrip: true, - decoded: 1000000000000 - }, - { - cbor: 'IA==', - hex: '20', - roundtrip: true, - decoded: -1 - }, - { - cbor: 'KQ==', - hex: '29', - roundtrip: true, - decoded: -10 - }, - { - cbor: 'OGM=', - hex: '3863', - roundtrip: true, - decoded: -100 - }, - { - cbor: 'OQPn', - hex: '3903e7', - roundtrip: true, - decoded: -1000 - }, - { - cbor: '+QAA', - hex: 'f90000', - roundtrip: true, - decoded: 0.0 - }, - { - cbor: '+TwA', - hex: 'f93c00', - roundtrip: true, - decoded: 1.0 - }, - { - cbor: '+z/xmZmZmZma', - hex: 'fb3ff199999999999a', - roundtrip: true, - decoded: 1.1 - }, - { - cbor: '+T4A', - hex: 'f93e00', - roundtrip: true, - decoded: 1.5 - }, - { - cbor: '+Xv/', - hex: 'f97bff', - roundtrip: true, - decoded: 65504.0 - }, - { - cbor: '+kfDUAA=', - hex: 'fa47c35000', - roundtrip: true, - decoded: 100000.0 - }, - { - cbor: '+n9///8=', - hex: 'fa7f7fffff', - roundtrip: true, - decoded: 3.4028234663852886e38 - }, - { - cbor: '+3435DyIAHWc', - hex: 'fb7e37e43c8800759c', - roundtrip: true, - decoded: 1.0e300 - }, - { - cbor: '+QAB', - hex: 'f90001', - roundtrip: true, - decoded: 5.960464477539063e-8 - }, - { - cbor: '+QQA', - hex: 'f90400', - roundtrip: true, - decoded: 6.103515625e-5 - }, - { - cbor: '+cQA', - hex: 'f9c400', - roundtrip: true, - decoded: -4.0 - }, - { - cbor: '+8AQZmZmZmZm', - hex: 'fbc010666666666666', - roundtrip: true, - decoded: -4.1 - }, { cbor: '9A==', hex: 'f4', @@ -285,10 +184,51 @@ const tests = [ describe('cbor decoder', () => { test.each(tests)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { - //@ts-ignore - const res = decodeCBOR(Buffer.from(hex, 'hex')); - console.log(decoded); - console.log(res); + const res = decodeCBOR(hexToBytes(hex)); expect(res).toEqual(decoded); }); }); + +describe('cbor encoder', () => { + test.each(tests)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { + const res = encodeCBOR(decoded); + expect(hex).toBe(bytesToHex(res)); + }); +}); + +describe('encode token back and forth', () => { + test('encode and decode token', () => { + const v3Token = { + memo: '', + token: [ + { + mint: 'http://localhost:3338', + proofs: [ + { + secret: 'acc12435e7b8484c3cf1850149218af90f716a52bf4a5ed347e48ecc13f77388', + C: '0244538319de485d55bed3b29a642bee5879375ab9e7a620e11e48ba482421f3cf', + id: '00ffd48b8f5ecf80', + amount: 1 + }, + { + secret: '1323d3d4707a58ad2e23ada4e9f1f49f5a5b4ac7b708eb0d61f738f48307e8ee', + C: '023456aa110d84b4ac747aebd82c3b005aca50bf457ebd5737a4414fac3ae7d94d', + id: '00ad268c4d1f5826', + amount: 2 + }, + { + secret: '56bcbcbb7cc6406b3fa5d57d2174f4eff8b4402b176926d3a57d3c3dcbb59d57', + C: '0273129c5719e599379a974a626363c333c56cafc0e6d01abe46d5808280789c63', + id: '00ad268c4d1f5826', + amount: 1 + } + ] + } + ] + }; + + const encoded = encodeCBOR(v3Token); + const decoded = decodeCBOR(encoded); + expect(decoded).toEqual(v3Token); + }); +}); From ebc56d990c4761f3aeb2123d2b08da917486d73a Mon Sep 17 00:00:00 2001 From: Egge Date: Thu, 25 Jul 2024 14:22:57 +0200 Subject: [PATCH 13/39] fixed string and array encoding --- src/cbor.ts | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/cbor.ts b/src/cbor.ts index 4a78889c5..df454d67d 100644 --- a/src/cbor.ts +++ b/src/cbor.ts @@ -40,14 +40,44 @@ function encodeUnsigned(value: number, buffer: Array) { function encodeString(value: string, buffer: Array) { const utf8 = new TextEncoder().encode(value); - encodeUnsigned(utf8.length, buffer); - buffer[buffer.length - 1] |= 0x60; - utf8.forEach((b) => buffer.push(b)); + const length = utf8.length; + + if (length < 24) { + buffer.push(0x60 + length); + } else if (length < 256) { + buffer.push(0x78, length); + } else if (length < 65536) { + buffer.push(0x79, (length >> 8) & 0xff, length & 0xff); + } else if (length < 4294967296) { + buffer.push( + 0x7a, + (length >> 24) & 0xff, + (length >> 16) & 0xff, + (length >> 8) & 0xff, + length & 0xff + ); + } else { + throw new Error('String too long to encode'); + } + + // Use a traditional for loop to iterate over Uint8Array + for (let i = 0; i < utf8.length; i++) { + buffer.push(utf8[i]); + } } function encodeArray(value: Array, buffer: Array) { - encodeUnsigned(value.length, buffer); - buffer[buffer.length - 1] |= 0x80; + const length = value.length; + if (length < 24) { + buffer.push(0x80 | length); + } else if (length < 256) { + buffer.push(0x98, length); + } else if (length < 65536) { + buffer.push(0x99, length >> 8, length & 0xff); + } else { + throw new Error('Unsupported array length'); + } + for (const item of value) { encodeItem(item, buffer); } From 0bf7ccc00136ccc22f1ce70bb80ee2215a7caf0d Mon Sep 17 00:00:00 2001 From: Egge Date: Fri, 26 Jul 2024 09:55:34 +0200 Subject: [PATCH 14/39] added cbor encoded tests --- test/cbor.test.ts | 101 ++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/test/cbor.test.ts b/test/cbor.test.ts index ada2df241..37809eea3 100644 --- a/test/cbor.test.ts +++ b/test/cbor.test.ts @@ -179,56 +179,71 @@ const tests = [ d: 'D', e: 'E' } + }, + { + cbor: 'RAECAwQ=', + hex: '4401020304', + roundtrip: true, + decoded: hexToBytes('01020304') } ]; -describe('cbor decoder', () => { - test.each(tests)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { - const res = decodeCBOR(hexToBytes(hex)); - expect(res).toEqual(decoded); - }); -}); +const mini = [ + { + cbor: 'RAECAwQ=', + hex: '4401020304', + roundtrip: true, + decoded: hexToBytes('01020304') + } +]; + +// describe('cbor decoder', () => { +// test.each(tests)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { +// const res = decodeCBOR(hexToBytes(hex)); +// expect(res).toEqual(decoded); +// }); +// }); describe('cbor encoder', () => { - test.each(tests)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { + test.each(mini)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { const res = encodeCBOR(decoded); expect(hex).toBe(bytesToHex(res)); }); }); -describe('encode token back and forth', () => { - test('encode and decode token', () => { - const v3Token = { - memo: '', - token: [ - { - mint: 'http://localhost:3338', - proofs: [ - { - secret: 'acc12435e7b8484c3cf1850149218af90f716a52bf4a5ed347e48ecc13f77388', - C: '0244538319de485d55bed3b29a642bee5879375ab9e7a620e11e48ba482421f3cf', - id: '00ffd48b8f5ecf80', - amount: 1 - }, - { - secret: '1323d3d4707a58ad2e23ada4e9f1f49f5a5b4ac7b708eb0d61f738f48307e8ee', - C: '023456aa110d84b4ac747aebd82c3b005aca50bf457ebd5737a4414fac3ae7d94d', - id: '00ad268c4d1f5826', - amount: 2 - }, - { - secret: '56bcbcbb7cc6406b3fa5d57d2174f4eff8b4402b176926d3a57d3c3dcbb59d57', - C: '0273129c5719e599379a974a626363c333c56cafc0e6d01abe46d5808280789c63', - id: '00ad268c4d1f5826', - amount: 1 - } - ] - } - ] - }; - - const encoded = encodeCBOR(v3Token); - const decoded = decodeCBOR(encoded); - expect(decoded).toEqual(v3Token); - }); -}); +// describe('encode token back and forth', () => { +// test('encode and decode token', () => { +// const v3Token = { +// memo: '', +// token: [ +// { +// mint: 'http://localhost:3338', +// proofs: [ +// { +// secret: 'acc12435e7b8484c3cf1850149218af90f716a52bf4a5ed347e48ecc13f77388', +// C: '0244538319de485d55bed3b29a642bee5879375ab9e7a620e11e48ba482421f3cf', +// id: '00ffd48b8f5ecf80', +// amount: 1 +// }, +// { +// secret: '1323d3d4707a58ad2e23ada4e9f1f49f5a5b4ac7b708eb0d61f738f48307e8ee', +// C: '023456aa110d84b4ac747aebd82c3b005aca50bf457ebd5737a4414fac3ae7d94d', +// id: '00ad268c4d1f5826', +// amount: 2 +// }, +// { +// secret: '56bcbcbb7cc6406b3fa5d57d2174f4eff8b4402b176926d3a57d3c3dcbb59d57', +// C: '0273129c5719e599379a974a626363c333c56cafc0e6d01abe46d5808280789c63', +// id: '00ad268c4d1f5826', +// amount: 1 +// } +// ] +// } +// ] +// }; +// +// const encoded = encodeCBOR(v3Token); +// const decoded = decodeCBOR(encoded); +// expect(decoded).toEqual(v3Token); +// }); +// }); From 62bb656fb0b006fb1b97f65809a46199292ddcf1 Mon Sep 17 00:00:00 2001 From: Egge Date: Fri, 26 Jul 2024 09:55:43 +0200 Subject: [PATCH 15/39] added bytestring encoding --- src/cbor.ts | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/cbor.ts b/src/cbor.ts index df454d67d..0436ff747 100644 --- a/src/cbor.ts +++ b/src/cbor.ts @@ -17,6 +17,8 @@ function encodeItem(value: any, buffer: Array) { encodeString(value, buffer); } else if (Array.isArray(value)) { encodeArray(value, buffer); + } else if (value instanceof Uint8Array) { + encodeByteString(value, buffer); } else if (typeof value === 'object') { encodeObject(value, buffer); } else { @@ -38,6 +40,32 @@ function encodeUnsigned(value: number, buffer: Array) { } } +function encodeByteString(value: Uint8Array, buffer: Array) { + const length = value.length; + + if (length < 24) { + buffer.push(0x40 + length); + } else if (length < 256) { + buffer.push(0x58, length); + } else if (length < 65536) { + buffer.push(0x59, (length >> 8) & 0xff, length & 0xff); + } else if (length < 4294967296) { + buffer.push( + 0x5a, + (length >> 24) & 0xff, + (length >> 16) & 0xff, + (length >> 8) & 0xff, + length & 0xff + ); + } else { + throw new Error('Byte string too long to encode'); + } + + for (let i = 0; i < value.length; i++) { + buffer.push(value[i]); + } +} + function encodeString(value: string, buffer: Array) { const utf8 = new TextEncoder().encode(value); const length = utf8.length; @@ -60,7 +88,6 @@ function encodeString(value: string, buffer: Array) { throw new Error('String too long to encode'); } - // Use a traditional for loop to iterate over Uint8Array for (let i = 0; i < utf8.length; i++) { buffer.push(utf8[i]); } From 319103a06196bcf163a1084e38c4e951eead573f Mon Sep 17 00:00:00 2001 From: Egge Date: Fri, 26 Jul 2024 09:55:53 +0200 Subject: [PATCH 16/39] added v4 encoding --- src/model/types/index.ts | 18 +++++++++++ src/utils.ts | 69 ++++++++++++++++++++++++++++++++++++---- test/utils.test.ts | 25 +++++++++++++++ 3 files changed, 106 insertions(+), 6 deletions(-) diff --git a/src/model/types/index.ts b/src/model/types/index.ts index e4cc4e44a..b1f9d52c6 100644 --- a/src/model/types/index.ts +++ b/src/model/types/index.ts @@ -565,3 +565,21 @@ export type InvoiceData = { memo?: string; expiry?: number; }; + +export type V4ProofTemplate = { + a: number; + s: string; + c: Uint8Array; +}; + +export type V4InnerToken = { + i: Uint8Array; + p: Array; +}; + +export type TokenV4Template = { + t: Array; + d: string; + m: string; + u: string; +}; diff --git a/src/utils.ts b/src/utils.ts index 1ace779b7..ec0b0f92f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,9 +1,24 @@ -import { encodeBase64ToJson, encodeBase64toUint8, encodeJsonToBase64 } from './base64.js'; -import { AmountPreference, Keys, Proof, Token, TokenEntry, TokenV2 } from './model/types/index.js'; +import { + encodeBase64ToJson, + encodeBase64toUint8, + encodeJsonToBase64, + encodeUint8toBase64 +} from './base64.js'; +import { + AmountPreference, + Keys, + Proof, + Token, + TokenEntry, + TokenV2, + TokenV4Template, + V4InnerToken, + V4ProofTemplate +} from './model/types/index.js'; import { TOKEN_PREFIX, TOKEN_VERSION } from './utils/Constants.js'; import { bytesToHex, hexToBytes } from '@noble/curves/abstract/utils'; import { sha256 } from '@noble/hashes/sha256'; -import { decodeCBOR } from './cbor.js'; +import { decodeCBOR, encodeCBOR } from './cbor.js'; function splitAmount(value: number, amountPreference?: Array): Array { const chunks: Array = []; @@ -77,6 +92,47 @@ function getEncodedToken(token: Token): string { return TOKEN_PREFIX + TOKEN_VERSION + encodeJsonToBase64(token); } +function getEncodedTokenV4(token: Token): string { + const idMap: { [id: string]: Array } = {}; + let mint: string | undefined = undefined; + for (let i = 0; i < token.token.length; i++) { + if (!mint) { + mint = token.token[i].mint; + } else { + if (mint !== token.token[i].mint) { + throw new Error('Multimint token can not be encoded as V4 token'); + } + } + for (let j = 0; j < token.token[i].proofs.length; j++) { + const proof = token.token[i].proofs[j]; + if (idMap[proof.id]) { + idMap[proof.id].push(proof); + } else { + idMap[proof.id] = [proof]; + } + } + } + const tokenTemplate: TokenV4Template = { + d: token.memo || '', + m: mint, + u: token.unit || 'sat', + t: Object.keys(idMap).map( + (id): V4InnerToken => ({ + i: hexToBytes(id), + p: idMap[id].map((p): V4ProofTemplate => ({ a: p.amount, s: p.secret, c: hexToBytes(p.C) })) + }) + ) + } as TokenV4Template; + + console.log(tokenTemplate.t[0].p[0]); + + const encodedData = encodeCBOR(tokenTemplate); + const prefix = 'cashu'; + const version = 'B'; + const base64Data = encodeUint8toBase64(encodedData); + return prefix + version + base64Data; +} + /** * Helper function to decode cashu tokens into object * @param token an encoded cashu token (cashuAey...) @@ -106,10 +162,11 @@ function handleTokens(token: string): Token { } else if (version === 'B') { const uInt8Token = encodeBase64toUint8(encodedToken); const tokenData = decodeCBOR(uInt8Token) as { - t: { p: { a: number; s: string; c: Uint8Array }[]; i: Uint8Array }[]; + t: Array<{ p: Array<{ a: number; s: string; c: Uint8Array }>; i: Uint8Array }>; m: string; d: string; }; + console.log(tokenData.t[0].p[0]); const mergedTokenEntry: TokenEntry = { mint: tokenData.m, proofs: [] }; tokenData.t.forEach((tokenEntry) => tokenEntry.p.forEach((p) => { @@ -122,9 +179,8 @@ function handleTokens(token: string): Token { }) ); return { token: [mergedTokenEntry], memo: tokenData.d || '' }; - } else { - throw new Error('Token version is not supported'); } + throw new Error('Token version is not supported'); } /** * Returns the keyset id of a set of keys @@ -180,6 +236,7 @@ export { bytesToNumber, getDecodedToken, getEncodedToken, + getEncodedTokenV4, hexToNumber, splitAmount, getDefaultAmountPreference diff --git a/test/utils.test.ts b/test/utils.test.ts index 1569cd782..fc241236e 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -182,3 +182,28 @@ describe('test keyset derivation', () => { expect(keysetId).toBe('009a1f293253e41e'); }); }); + +describe('test v4 encoding', () => { + test('standard token', async () => { + const v3Token = { + memo: 'Thank you', + token: [ + { + mint: 'http://localhost:3338', + proofs: [ + { + secret: '9a6dbb847bd232ba76db0df197216b29d3b8cc14553cd27827fc1cc942fedb4e', + C: '038618543ffb6b8695df4ad4babcde92a34a96bdcd97dcee0d7ccf98d472126792', + id: '00ad268c4d1f5826', + amount: 1 + } + ] + } + ] + }; + const encoded = utils.getEncodedTokenV4(v3Token); + console.log(encoded); + const decoded = utils.getDecodedToken(encoded); + console.log(decoded); + }); +}); From 0de0f12a6924ea363eb64ab1bd19c73f1cbd5111 Mon Sep 17 00:00:00 2001 From: Egge Date: Fri, 26 Jul 2024 11:31:56 +0200 Subject: [PATCH 17/39] added raw token tests --- test/cbor.test.ts | 103 +++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 52 deletions(-) diff --git a/test/cbor.test.ts b/test/cbor.test.ts index 37809eea3..be209adbc 100644 --- a/test/cbor.test.ts +++ b/test/cbor.test.ts @@ -188,62 +188,61 @@ const tests = [ } ]; -const mini = [ - { - cbor: 'RAECAwQ=', - hex: '4401020304', - roundtrip: true, - decoded: hexToBytes('01020304') - } -]; - -// describe('cbor decoder', () => { -// test.each(tests)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { -// const res = decodeCBOR(hexToBytes(hex)); -// expect(res).toEqual(decoded); -// }); -// }); +describe('cbor decoder', () => { + test.each(tests)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { + const res = decodeCBOR(hexToBytes(hex)); + expect(res).toEqual(decoded); + }); +}); describe('cbor encoder', () => { - test.each(mini)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { + test.each(tests)('given $hex as arguments, returns $decoded', ({ hex, decoded }) => { const res = encodeCBOR(decoded); expect(hex).toBe(bytesToHex(res)); }); }); -// describe('encode token back and forth', () => { -// test('encode and decode token', () => { -// const v3Token = { -// memo: '', -// token: [ -// { -// mint: 'http://localhost:3338', -// proofs: [ -// { -// secret: 'acc12435e7b8484c3cf1850149218af90f716a52bf4a5ed347e48ecc13f77388', -// C: '0244538319de485d55bed3b29a642bee5879375ab9e7a620e11e48ba482421f3cf', -// id: '00ffd48b8f5ecf80', -// amount: 1 -// }, -// { -// secret: '1323d3d4707a58ad2e23ada4e9f1f49f5a5b4ac7b708eb0d61f738f48307e8ee', -// C: '023456aa110d84b4ac747aebd82c3b005aca50bf457ebd5737a4414fac3ae7d94d', -// id: '00ad268c4d1f5826', -// amount: 2 -// }, -// { -// secret: '56bcbcbb7cc6406b3fa5d57d2174f4eff8b4402b176926d3a57d3c3dcbb59d57', -// C: '0273129c5719e599379a974a626363c333c56cafc0e6d01abe46d5808280789c63', -// id: '00ad268c4d1f5826', -// amount: 1 -// } -// ] -// } -// ] -// }; -// -// const encoded = encodeCBOR(v3Token); -// const decoded = decodeCBOR(encoded); -// expect(decoded).toEqual(v3Token); -// }); -// }); +describe('raw v4 token cbor en/decoding', () => { + const expectedBase64 = + 'o2F0gqJhaUgA_9SLj17PgGFwgaNhYQFhc3hAYWNjMTI0MzVlN2I4NDg0YzNjZjE4NTAxNDkyMThhZjkwZjcxNmE1MmJmNGE1ZWQzNDdlNDhlY2MxM2Y3NzM4OGFjWCECRFODGd5IXVW-07KaZCvuWHk3WrnnpiDhHki6SCQh88-iYWlIAK0mjE0fWCZhcIKjYWECYXN4QDEzMjNkM2Q0NzA3YTU4YWQyZTIzYWRhNGU5ZjFmNDlmNWE1YjRhYzdiNzA4ZWIwZDYxZjczOGY0ODMwN2U4ZWVhY1ghAjRWqhENhLSsdHrr2Cw7AFrKUL9Ffr1XN6RBT6w659lNo2FhAWFzeEA1NmJjYmNiYjdjYzY0MDZiM2ZhNWQ1N2QyMTc0ZjRlZmY4YjQ0MDJiMTc2OTI2ZDNhNTdkM2MzZGNiYjU5ZDU3YWNYIQJzEpxXGeWZN5qXSmJjY8MzxWyvwObQGr5G1YCCgHicY2FtdWh0dHA6Ly9sb2NhbGhvc3Q6MzMzOGF1Y3NhdA=='; + const token = { + t: [ + { + i: hexToBytes('00ffd48b8f5ecf80'), + p: [ + { + a: 1, + s: 'acc12435e7b8484c3cf1850149218af90f716a52bf4a5ed347e48ecc13f77388', + c: hexToBytes('0244538319de485d55bed3b29a642bee5879375ab9e7a620e11e48ba482421f3cf') + } + ] + }, + { + i: hexToBytes('00ad268c4d1f5826'), + p: [ + { + a: 2, + s: '1323d3d4707a58ad2e23ada4e9f1f49f5a5b4ac7b708eb0d61f738f48307e8ee', + c: hexToBytes('023456aa110d84b4ac747aebd82c3b005aca50bf457ebd5737a4414fac3ae7d94d') + }, + { + a: 1, + s: '56bcbcbb7cc6406b3fa5d57d2174f4eff8b4402b176926d3a57d3c3dcbb59d57', + c: hexToBytes('0273129c5719e599379a974a626363c333c56cafc0e6d01abe46d5808280789c63') + } + ] + } + ], + m: 'http://localhost:3338', + u: 'sat' + }; + test('encode v4 raw', () => { + const encoded = encodeCBOR(token); + const encodedString = Buffer.from(encoded).toString('base64url'); + expect(encodedString).toBe(expectedBase64.replace(/\=+$/, '')); + }); + test('decode v4 raw', () => { + const decoded = decodeCBOR(Buffer.from(expectedBase64.replace(/\=+$/, ''), 'base64url')); + expect(decoded).toEqual(token); + }); +}); From c5bd1ae4a45a26242a6fe99e35842fbc87499a54 Mon Sep 17 00:00:00 2001 From: Egge Date: Fri, 26 Jul 2024 11:37:40 +0200 Subject: [PATCH 18/39] added base64url encoder --- src/base64.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/base64.ts b/src/base64.ts index 7f1b09237..266bb7d4a 100644 --- a/src/base64.ts +++ b/src/base64.ts @@ -4,6 +4,10 @@ function encodeUint8toBase64(uint8array: Uint8Array): string { return Buffer.from(uint8array).toString('base64'); } +function encodeUint8toBase64Url(bytes: Uint8Array): string { + return Buffer.from(bytes).toString('base64url').replace(/\=+$/, ''); +} + function encodeBase64toUint8(base64String: string): Uint8Array { return Buffer.from(base64String, 'base64'); } @@ -29,4 +33,10 @@ function base64urlFromBase64(str: string) { // .replace(/=/g, '.'); } -export { encodeUint8toBase64, encodeBase64toUint8, encodeJsonToBase64, encodeBase64ToJson }; +export { + encodeUint8toBase64, + encodeUint8toBase64Url, + encodeBase64toUint8, + encodeJsonToBase64, + encodeBase64ToJson +}; From f75c6c42126d89221e0120f1e57e26c03c565c3d Mon Sep 17 00:00:00 2001 From: Egge Date: Fri, 26 Jul 2024 11:37:58 +0200 Subject: [PATCH 19/39] adjusted b64 v4 encoder --- src/utils.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index ec0b0f92f..3a6d95e70 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,7 +2,8 @@ import { encodeBase64ToJson, encodeBase64toUint8, encodeJsonToBase64, - encodeUint8toBase64 + encodeUint8toBase64, + encodeUint8toBase64Url } from './base64.js'; import { AmountPreference, @@ -124,12 +125,10 @@ function getEncodedTokenV4(token: Token): string { ) } as TokenV4Template; - console.log(tokenTemplate.t[0].p[0]); - const encodedData = encodeCBOR(tokenTemplate); const prefix = 'cashu'; const version = 'B'; - const base64Data = encodeUint8toBase64(encodedData); + const base64Data = encodeUint8toBase64Url(encodedData); return prefix + version + base64Data; } From 062769cfee012d368d5bcdbfd07927e648eea434 Mon Sep 17 00:00:00 2001 From: Egge Date: Mon, 5 Aug 2024 18:00:20 +0200 Subject: [PATCH 20/39] fixed unit and memo --- src/utils.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 3a6d95e70..6cf6d5279 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -114,7 +114,6 @@ function getEncodedTokenV4(token: Token): string { } } const tokenTemplate: TokenV4Template = { - d: token.memo || '', m: mint, u: token.unit || 'sat', t: Object.keys(idMap).map( @@ -125,6 +124,10 @@ function getEncodedTokenV4(token: Token): string { ) } as TokenV4Template; + if (token.memo) { + tokenTemplate.d = token.memo; + } + const encodedData = encodeCBOR(tokenTemplate); const prefix = 'cashu'; const version = 'B'; @@ -164,6 +167,7 @@ function handleTokens(token: string): Token { t: Array<{ p: Array<{ a: number; s: string; c: Uint8Array }>; i: Uint8Array }>; m: string; d: string; + u: string; }; console.log(tokenData.t[0].p[0]); const mergedTokenEntry: TokenEntry = { mint: tokenData.m, proofs: [] }; @@ -177,7 +181,7 @@ function handleTokens(token: string): Token { }); }) ); - return { token: [mergedTokenEntry], memo: tokenData.d || '' }; + return { token: [mergedTokenEntry], memo: tokenData.d || '', unit: tokenData.u || 'sat' }; } throw new Error('Token version is not supported'); } From 948b2f3ca3b32aceab7e1c8703f3b103356b5453 Mon Sep 17 00:00:00 2001 From: Egge Date: Mon, 5 Aug 2024 18:00:33 +0200 Subject: [PATCH 21/39] added more test vectors --- test/utils.test.ts | 53 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/test/utils.test.ts b/test/utils.test.ts index fc241236e..c686b8992 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -116,6 +116,7 @@ describe('test decode token', () => { test('testing v4 Token', () => { const v3Token = { memo: 'Thank you', + unit: 'sat', token: [ { mint: 'http://localhost:3338', @@ -140,6 +141,7 @@ describe('test decode token', () => { test('testing v4 Token with multi keyset', () => { const v3Token = { memo: '', + unit: 'sat', token: [ { mint: 'http://localhost:3338', @@ -185,6 +187,8 @@ describe('test keyset derivation', () => { describe('test v4 encoding', () => { test('standard token', async () => { + const encodedV4 = + 'cashuBpGF0gaJhaUgArSaMTR9YJmFwgaNhYQFhc3hAOWE2ZGJiODQ3YmQyMzJiYTc2ZGIwZGYxOTcyMTZiMjlkM2I4Y2MxNDU1M2NkMjc4MjdmYzFjYzk0MmZlZGI0ZWFjWCEDhhhUP_trhpXfStS6vN6So0qWvc2X3O4NfM-Y1HISZ5JhZGlUaGFuayB5b3VhbXVodHRwOi8vbG9jYWxob3N0OjMzMzhhdWNzYXQ='; const v3Token = { memo: 'Thank you', token: [ @@ -199,11 +203,52 @@ describe('test v4 encoding', () => { } ] } - ] + ], + unit: 'sat' + }; + const encoded = utils.getEncodedTokenV4(v3Token); + const decodedEncodedToken = utils.getDecodedToken(encoded); + const decodedExpectedToken = utils.getDecodedToken(encodedV4); + expect(decodedEncodedToken).toEqual(v3Token); + expect(decodedExpectedToken).toEqual(decodedEncodedToken); + }); + test('multi Id token', async () => { + const encodedV4 = + 'cashuBo2F0gqJhaUgA_9SLj17PgGFwgaNhYQFhc3hAYWNjMTI0MzVlN2I4NDg0YzNjZjE4NTAxNDkyMThhZjkwZjcxNmE1MmJmNGE1ZWQzNDdlNDhlY2MxM2Y3NzM4OGFjWCECRFODGd5IXVW-07KaZCvuWHk3WrnnpiDhHki6SCQh88-iYWlIAK0mjE0fWCZhcIKjYWECYXN4QDEzMjNkM2Q0NzA3YTU4YWQyZTIzYWRhNGU5ZjFmNDlmNWE1YjRhYzdiNzA4ZWIwZDYxZjczOGY0ODMwN2U4ZWVhY1ghAjRWqhENhLSsdHrr2Cw7AFrKUL9Ffr1XN6RBT6w659lNo2FhAWFzeEA1NmJjYmNiYjdjYzY0MDZiM2ZhNWQ1N2QyMTc0ZjRlZmY4YjQ0MDJiMTc2OTI2ZDNhNTdkM2MzZGNiYjU5ZDU3YWNYIQJzEpxXGeWZN5qXSmJjY8MzxWyvwObQGr5G1YCCgHicY2FtdWh0dHA6Ly9sb2NhbGhvc3Q6MzMzOGF1Y3NhdA'; + const v3Token = { + token: [ + { + mint: 'http://localhost:3338', + proofs: [ + { + secret: 'acc12435e7b8484c3cf1850149218af90f716a52bf4a5ed347e48ecc13f77388', + C: '0244538319de485d55bed3b29a642bee5879375ab9e7a620e11e48ba482421f3cf', + id: '00ffd48b8f5ecf80', + amount: 1 + }, + { + secret: '1323d3d4707a58ad2e23ada4e9f1f49f5a5b4ac7b708eb0d61f738f48307e8ee', + C: '023456aa110d84b4ac747aebd82c3b005aca50bf457ebd5737a4414fac3ae7d94d', + id: '00ad268c4d1f5826', + amount: 2 + }, + { + secret: '56bcbcbb7cc6406b3fa5d57d2174f4eff8b4402b176926d3a57d3c3dcbb59d57', + C: '0273129c5719e599379a974a626363c333c56cafc0e6d01abe46d5808280789c63', + id: '00ad268c4d1f5826', + amount: 1 + } + ] + } + ], + memo: '', + unit: 'sat' }; + const encoded = utils.getEncodedTokenV4(v3Token); - console.log(encoded); - const decoded = utils.getDecodedToken(encoded); - console.log(decoded); + const decodedEncodedToken = utils.getDecodedToken(encoded); + const decodedExpectedToken = utils.getDecodedToken(encodedV4); + expect(decodedEncodedToken).toEqual(v3Token); + expect(decodedExpectedToken).toEqual(decodedEncodedToken); }); }); From 35448608450f0a0693665ef36bbf1e3fb246fc91 Mon Sep 17 00:00:00 2001 From: Egge Date: Tue, 6 Aug 2024 05:53:44 +0200 Subject: [PATCH 22/39] removed logs, added export --- src/index.ts | 3 ++- src/utils.ts | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index efa9c23f3..530629f13 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,7 +2,7 @@ import { CashuMint } from './CashuMint.js'; import { CashuWallet } from './CashuWallet.js'; import { setGlobalRequestOptions } from './request.js'; import { generateNewMnemonic, deriveSeedFromMnemonic } from '@cashu/crypto/modules/client/NUT09'; -import { getEncodedToken, getDecodedToken, deriveKeysetId } from './utils.js'; +import { getEncodedToken, getEncodedTokenV4, getDecodedToken, deriveKeysetId } from './utils.js'; export * from './model/types/index.js'; @@ -11,6 +11,7 @@ export { CashuWallet, getDecodedToken, getEncodedToken, + getEncodedTokenV4, deriveKeysetId, generateNewMnemonic, deriveSeedFromMnemonic, diff --git a/src/utils.ts b/src/utils.ts index 6cf6d5279..00d6ec012 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -169,7 +169,6 @@ function handleTokens(token: string): Token { d: string; u: string; }; - console.log(tokenData.t[0].p[0]); const mergedTokenEntry: TokenEntry = { mint: tokenData.m, proofs: [] }; tokenData.t.forEach((tokenEntry) => tokenEntry.p.forEach((p) => { From ec9533b5b8a25cd491dbe95867b7caa1a3fabbd8 Mon Sep 17 00:00:00 2001 From: Egge Date: Mon, 12 Aug 2024 16:00:49 +0200 Subject: [PATCH 23/39] bumped version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ee763349..109d21187 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cashu/cashu-ts", - "version": "1.0.1", + "version": "1.1.0-1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@cashu/cashu-ts", - "version": "1.0.1", + "version": "1.1.0-1", "license": "MIT", "dependencies": { "@cashu/crypto": "^0.2.6", diff --git a/package.json b/package.json index 58980401e..a04b15dbb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cashu/cashu-ts", - "version": "1.0.1", + "version": "1.1.0-1", "description": "cashu library for communicating with a cashu mint", "main": "dist/lib/es5/index.js", "module": "dist/lib/es6/index.js", From 630865b727caecd7c2c3a63393289d5e4416415b Mon Sep 17 00:00:00 2001 From: Caleb Beery Date: Wed, 17 Jul 2024 18:40:43 -0700 Subject: [PATCH 24/39] Refactored types into a more organized hierarchy. --- src/model/types/index.ts | 559 +--------------------------- src/model/types/mint/index.ts | 21 ++ src/model/types/mint/keys.ts | 60 +++ src/model/types/mint/responses.ts | 217 +++++++++++ src/model/types/wallet/index.ts | 65 ++++ src/model/types/wallet/payloads.ts | 133 +++++++ src/model/types/wallet/responses.ts | 47 +++ src/model/types/wallet/tokens.ts | 32 ++ 8 files changed, 577 insertions(+), 557 deletions(-) create mode 100644 src/model/types/mint/index.ts create mode 100644 src/model/types/mint/keys.ts create mode 100644 src/model/types/mint/responses.ts create mode 100644 src/model/types/wallet/index.ts create mode 100644 src/model/types/wallet/payloads.ts create mode 100644 src/model/types/wallet/responses.ts create mode 100644 src/model/types/wallet/tokens.ts diff --git a/src/model/types/index.ts b/src/model/types/index.ts index b1f9d52c6..b409e7ea3 100644 --- a/src/model/types/index.ts +++ b/src/model/types/index.ts @@ -1,560 +1,5 @@ -/** - * represents a single Cashu proof. - */ -export type Proof = { - /** - * Keyset id, used to link proofs to a mint an its MintKeys. - */ - id: string; - /** - * Amount denominated in Satoshis. Has to match the amount of the mints signing key. - */ - amount: number; - /** - * The initial secret that was (randomly) chosen for the creation of this proof. - */ - secret: string; - /** - * The unblinded signature for this secret, signed by the mints private key. - */ - C: string; -}; - -/** - * Public keys are a dictionary of number and string. The number represents the amount that the key signs for. - */ -export type Keys = { [amount: number]: string }; - -/** - * An array of mint keysets - */ -export type MintActiveKeys = { - /** - * Keysets - */ - keysets: Array; -}; - -/** - * A mint keyset. - */ -export type MintKeys = { - /** - * Keyset ID - */ - id: string; - /** - * Unit of the keyset. - */ - unit: string; - /** - * Public keys are a dictionary of number and string. The number represents the amount that the key signs for. - */ - keys: Keys; -}; - -/** - * An array of mint keyset entries. - */ -export type MintAllKeysets = { - /** - * Keysets - */ - keysets: Array; -}; - -/** - * A mint keyset entry. - */ -export type MintKeyset = { - /** - * Keyset ID - */ - id: string; - /** - * Unit of the keyset. - */ - unit: string; - /** - * Whether the keyset is active or not. - */ - active: boolean; -}; - -/** - * response when after receiving a single TokenEntry - */ -export type ReceiveTokenEntryResponse = { - /** - * Received proofs - */ - proofs: Array; -}; - -/** - * response after sending - */ -export type SendResponse = { - /** - * Proofs that exceeded the needed amount - */ - returnChange: Array; - /** - * Proofs to be sent, matching the chosen amount - */ - send: Array; -}; -/** - * Response when receiving a complete token. - */ -export type ReceiveResponse = { - /** - * Successfully received Cashu Token - */ - token: Token; - /** - * TokenEntries that had errors. No error will be thrown, but clients can choose to handle tokens with errors accordingly. - */ - tokensWithErrors: Token | undefined; -}; - -/** - * Payload that needs to be sent to the mint when paying a lightning invoice. - */ -export type PaymentPayload = { - /** - * Payment request/Lighting invoice that should get paid by the mint. - */ - pr: string; - /** - * Proofs, matching Lightning invoices amount + fees. - */ - proofs: Array; -}; - -/** - * Payload that needs to be send to the mint to request a melt quote - */ -export type MeltQuotePayload = { - /** - * Unit to be melted - */ - unit: string; - /** - * Request to be melted to - */ - request: string; -}; - -export enum MeltQuoteState { - UNPAID = 'UNPAID', - PENDING = 'PENDING', - PAID = 'PAID' -} - -/** - * Response from the mint after requesting a melt quote - */ -export type MeltQuoteResponse = { - /** - * Quote ID - */ - quote: string; - /** - * Amount to be melted - */ - amount: number; - /** - * Fee reserve to be added to the amount - */ - fee_reserve: number; - /** - * State of the melt quote - */ - state: MeltQuoteState; - /** - * Timestamp of when the quote expires - */ - expiry: number; - /** - * preimage of the paid invoice. is null if it the invoice has not been paid yet. can be null, depending on which LN-backend the mint uses - */ - payment_preimage: string | null; - /** - * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate - */ - change?: Array; -} & ApiError; - -/** - * Payload that needs to be sent to the mint when melting. Includes Return for overpaid fees - */ -export type MeltPayload = { - /** - * ID of the melt quote - */ - quote: string; - /** - * Inputs (Proofs) to be melted - */ - inputs: Array; - /** - * Blank outputs (blinded messages) that can be filled by the mint to return overpaid fees - */ - outputs: Array; -}; - -/** - * Response after paying a Lightning invoice - */ -export type MeltTokensResponse = { - /** - * if false, the proofs have not been invalidated and the payment can be tried later again with the same proofs - */ - isPaid: boolean; - /** - * preimage of the paid invoice. can be null, depending on which LN-backend the mint uses - */ - preimage: string | null; - /** - * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate - */ - change: Array; -}; - -/** - * Payload that needs to be sent to the mint when performing a split action - */ -export type SwapPayload = { - /** - * Inputs to the split operation - */ - inputs: Array; - /** - * Outputs (blinded messages) to be signed by the mint - */ - outputs: Array; -}; -/** - * Response from the mint after performing a split action - */ -export type SwapResponse = { - /** - * represents the outputs after the split - */ - signatures: Array; -} & ApiError; - -/** - * Cashu api error - */ -export type ApiError = { - /** - * Error message - */ - error?: string; - /** - * HTTP error code - */ - code?: number; - /** - * Detailed error message - */ - detail?: string; -}; - -/** - * Payload that needs to be sent to the mint when requesting a mint - */ -export type MintQuotePayload = { - /** - * Unit to be minted - */ - unit: string; - /** - * Amount to be minted - */ - amount: number; -}; - -export enum MintQuoteState { - UNPAID = 'UNPAID', - PAID = 'PAID', - ISSUED = 'ISSUED' -} - -/** - * Response from the mint after requesting a mint - */ -export type MintQuoteResponse = { - /** - * Payment request - */ - request: string; - /** - * Quote ID - */ - quote: string; - /** - * State of the mint quote - */ - state: MintQuoteState; - /** - * Timestamp of when the quote expires - */ - expiry: number; -} & ApiError; - -/** - * Payload that needs to be sent to the mint when requesting a mint - */ -export type MintPayload = { - /** - * Quote ID received from the mint. - */ - quote: string; - /** - * Outputs (blinded messages) to be signed by the mint. - */ - outputs: Array; -}; -/** - * Response from the mint after requesting a mint - */ -export type MintResponse = { - signatures: Array; -} & ApiError; - -/** - * Payload that needs to be sent to the mint when checking for spendable proofs - */ -export type CheckStatePayload = { - /** - * The Y = hash_to_curve(secret) of the proofs to be checked. - */ - Ys: Array; -}; - -/** - * Enum for the state of a proof - */ -export enum CheckStateEnum { - UNSPENT = 'UNSPENT', - PENDING = 'PENDING', - SPENT = 'SPENT' -} - -/** - * Entries of CheckStateResponse with state of the proof - */ -export type CheckStateEntry = { - Y: string; - state: CheckStateEnum; - witness: string | null; -}; - -/** - * Response when checking proofs if they are spendable. Should not rely on this for receiving, since it can be easily cheated. - */ -export type CheckStateResponse = { - /** - * - */ - states: Array; -} & ApiError; -/** - * blinded message for sending to the mint - */ -export type SerializedBlindedMessage = { - /** - * amount - */ - amount: number; - /** - * Blinded message - */ - B_: string; - /** - * Keyset id - */ - id: string; -}; -/** - * Blinded signature as it is received from the mint - */ -export type SerializedBlindedSignature = { - /** - * keyset id for indicating which public key was used to sign the blinded message - */ - id: string; - /** - * Amount denominated in Satoshi - */ - amount: number; - /** - * Blinded signature - */ - C_: string; -}; - -/** - * A Cashu token - */ -export type Token = { - /** - * token entries - */ - token: Array; - /** - * a message to send along with the token - */ - memo?: string; - /** - * the unit of the token - */ - unit?: string; -}; -/** - * TokenEntry that stores proofs and mints - */ -export type TokenEntry = { - /** - * a list of proofs - */ - proofs: Array; - /** - * the mints URL - */ - mint: string; -}; -/** - * @deprecated Token V2 - * should no longer be used - */ -export type TokenV2 = { - proofs: Array; - mints: Array<{ url: string; ids: Array }>; -}; - -/** - * Data that the library needs to hold in memory while it awaits the blinded signatures for the mint. It is later used for unblinding the signatures. - */ -export type BlindedTransaction = { - /** - * Blinded messages sent to the mint for signing. - */ - blindedMessages: Array; - /** - * secrets, kept client side for constructing proofs later. - */ - secrets: Array; - /** - * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. - */ - rs: Array; - /** - * amounts denominated in Satoshi - */ - amounts: Array; -}; - -/** - * Data that the library needs to hold in memory while it awaits the blinded signatures for the mint. It is later used for unblinding the signatures. - */ -export type BlindedMessageData = { - /** - * Blinded messages sent to the mint for signing. - */ - blindedMessages: Array; - /** - * secrets, kept client side for constructing proofs later. - */ - secrets: Array; - /** - * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. - */ - rs: Array; -}; - -export type MintContactInfo = { - method: string; - info: string; -}; - -/** - * Response from mint at /info endpoint - */ -export type GetInfoResponse = { - name: string; - pubkey: string; - version: string; - description?: string; - description_long?: string; - contact: Array; - nuts: { - '4': { - methods: Array; - disabled: boolean; - }; - '5': { - methods: Array; - disabled: boolean; - }; - '7'?: { - supported: boolean; - }; - '8'?: { - supported: boolean; - }; - '9'?: { - supported: boolean; - }; - '10'?: { - supported: boolean; - }; - '11'?: { - supported: boolean; - }; - '12'?: { - supported: boolean; - }; - '13'?: { - supported: boolean; - }; - }; - motd?: string; -}; - -/** - * Ecash to other MoE swap method, displayed in @type {GetInfoResponse} - */ -export type SwapMethod = { - method: string; - unit: string; - min_amount: number; - max_amount: number; -}; - -/** - * Request to mint at /v1/restore endpoint - */ - -export type PostRestorePayload = { - outputs: Array; -}; - -/** - * Response from mint at /v1/restore endpoint - */ -export type PostRestoreResponse = { - outputs: Array; - promises: Array; -}; - -export type AmountPreference = { - amount: number; - count: number; -}; +export * from "./mint/index" +export * from "./wallet/index" export type InvoiceData = { paymentRequest: string; diff --git a/src/model/types/mint/index.ts b/src/model/types/mint/index.ts new file mode 100644 index 000000000..79a5786fe --- /dev/null +++ b/src/model/types/mint/index.ts @@ -0,0 +1,21 @@ +import {SerializedBlindedMessage} from "../wallet"; + +export * from "./responses" +export * from "./keys" + +/** + * Payload that needs to be sent to the mint when checking for spendable proofs + */ +export type CheckStatePayload = { + /** + * The Y = hash_to_curve(secret) of the proofs to be checked. + */ + Ys: Array; +}; + +/** + * Request to mint at /v1/restore endpoint + */ +export type PostRestorePayload = { + outputs: Array; +}; diff --git a/src/model/types/mint/keys.ts b/src/model/types/mint/keys.ts new file mode 100644 index 000000000..38c1905ce --- /dev/null +++ b/src/model/types/mint/keys.ts @@ -0,0 +1,60 @@ +/** + * Public keys are a dictionary of number and string. The number represents the amount that the key signs for. + */ +export type Keys = { [amount: number]: string }; + +/** + * An array of mint keysets + */ +export type MintActiveKeys = { + /** + * Keysets + */ + keysets: Array; +}; + +/** + * An array of mint keyset entries. + */ +export type MintAllKeysets = { + /** + * Keysets + */ + keysets: Array; +}; + +/** + * A mint keyset. + */ +export type MintKeys = { + /** + * Keyset ID + */ + id: string; + /** + * Unit of the keyset. + */ + unit: string; + /** + * Public keys are a dictionary of number and string. The number represents the amount that the key signs for. + */ + keys: Keys; +}; + +/** + * A mint keyset entry. + */ +export type MintKeyset = { + /** + * Keyset ID + */ + id: string; + /** + * Unit of the keyset. + */ + unit: string; + /** + * Whether the keyset is active or not. + */ + active: boolean; +}; diff --git a/src/model/types/mint/responses.ts b/src/model/types/mint/responses.ts new file mode 100644 index 000000000..5c91058f9 --- /dev/null +++ b/src/model/types/mint/responses.ts @@ -0,0 +1,217 @@ +import {SerializedBlindedMessage} from "../wallet"; + +/** + * Cashu api error + */ +export type ApiError = { + /** + * Error message + */ + error?: string; + /** + * HTTP error code + */ + code?: number; + /** + * Detailed error message + */ + detail?: string; +}; + +/** + * Entries of CheckStateResponse with state of the proof + */ +export type CheckStateEntry = { + Y: string; + state: CheckStateEnum; + witness: string | null; +}; + +/** + * Enum for the state of a proof + */ +export enum CheckStateEnum { + UNSPENT = 'UNSPENT', + PENDING = 'PENDING', + SPENT = 'SPENT' +} + +/** + * Response when checking proofs if they are spendable. Should not rely on this for receiving, since it can be easily cheated. + */ +export type CheckStateResponse = { + /** + * + */ + states: Array; +} & ApiError; + +/** + * Response from mint at /info endpoint + */ +export type GetInfoResponse = { + name: string; + pubkey: string; + version: string; + description?: string; + description_long?: string; + contact: Array; + nuts: { + '4': { + methods: Array; + disabled: boolean; + }; + '5': { + methods: Array; + disabled: boolean; + }; + '7'?: { + supported: boolean; + }; + '8'?: { + supported: boolean; + }; + '9'?: { + supported: boolean; + }; + '10'?: { + supported: boolean; + }; + '11'?: { + supported: boolean; + }; + '12'?: { + supported: boolean; + }; + '13'?: { + supported: boolean; + }; + }; + motd?: string; +}; + +/** + * Response from the mint after requesting a melt quote + */ +export type MeltQuoteResponse = { + /** + * Quote ID + */ + quote: string; + /** + * Amount to be melted + */ + amount: number; + /** + * Fee reserve to be added to the amount + */ + fee_reserve: number; + /** + * State of the melt quote + */ + state: MeltQuoteState; + /** + * Timestamp of when the quote expires + */ + expiry: number; + /** + * preimage of the paid invoice. is null if it the invoice has not been paid yet. can be null, depending on which LN-backend the mint uses + */ + payment_preimage: string | null; + /** + * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate + */ + change?: Array; +} & ApiError; + +export enum MeltQuoteState { + UNPAID = 'UNPAID', + PENDING = 'PENDING', + PAID = 'PAID' +} + +export type MintContactInfo = { + method: string; + info: string; +}; + +export enum MintQuoteState { + UNPAID = 'UNPAID', + PAID = 'PAID', + ISSUED = 'ISSUED' +} + +/** + * Response from the mint after requesting a mint + */ +export type MintQuoteResponse = { + /** + * Payment request + */ + request: string; + /** + * Quote ID + */ + quote: string; + /** + * State of the mint quote + */ + state: MintQuoteState; + /** + * Timestamp of when the quote expires + */ + expiry: number; +} & ApiError; + +/** + * Response from the mint after requesting a mint + */ +export type MintResponse = { + signatures: Array; +} & ApiError; + +/** + * Response from mint at /v1/restore endpoint + */ +export type PostRestoreResponse = { + outputs: Array; + promises: Array; +}; + +/** + * Blinded signature as it is received from the mint + */ +export type SerializedBlindedSignature = { + /** + * keyset id for indicating which public key was used to sign the blinded message + */ + id: string; + /** + * Amount denominated in Satoshi + */ + amount: number; + /** + * Blinded signature + */ + C_: string; +}; + +/** + * Ecash to other MoE swap method, displayed in @type {GetInfoResponse} + */ +export type SwapMethod = { + method: string; + unit: string; + min_amount: number; + max_amount: number; +}; + +/** + * Response from the mint after performing a split action + */ +export type SwapResponse = { + /** + * represents the outputs after the split + */ + signatures: Array; +} & ApiError; diff --git a/src/model/types/wallet/index.ts b/src/model/types/wallet/index.ts new file mode 100644 index 000000000..c14b10c9b --- /dev/null +++ b/src/model/types/wallet/index.ts @@ -0,0 +1,65 @@ +export * from "./payloads" +export * from "./responses" +export * from "./tokens" + +export type AmountPreference = { + amount: number; + count: number; +}; + +/** + * represents a single Cashu proof. + */ +export type Proof = { + /** + * Keyset id, used to link proofs to a mint an its MintKeys. + */ + id: string; + /** + * Amount denominated in Satoshis. Has to match the amount of the mints signing key. + */ + amount: number; + /** + * The initial secret that was (randomly) chosen for the creation of this proof. + */ + secret: string; + /** + * The unblinded signature for this secret, signed by the mints private key. + */ + C: string; +}; + +/** + * response when after receiving a single TokenEntry + */ +export type ReceiveTokenEntryResponse = { + /** + * Received proofs + */ + proofs: Array; +}; + + +/** + * Payload that needs to be sent to the mint when paying a lightning invoice. + */ +export type PaymentPayload = { + /** + * Payment request/Lighting invoice that should get paid by the mint. + */ + pr: string; + /** + * Proofs, matching Lightning invoices amount + fees. + */ + proofs: Array; +}; + + +/** + * @deprecated Token V2 + * should no longer be used + */ +export type TokenV2 = { + proofs: Array; + mints: Array<{ url: string; ids: Array }>; +}; diff --git a/src/model/types/wallet/payloads.ts b/src/model/types/wallet/payloads.ts new file mode 100644 index 000000000..73021cd7b --- /dev/null +++ b/src/model/types/wallet/payloads.ts @@ -0,0 +1,133 @@ +import {Proof} from "./index"; + +/** + * Data that the library needs to hold in memory while it awaits the blinded signatures for the mint. It is later used for unblinding the signatures. + */ +export type BlindedMessageData = { + /** + * Blinded messages sent to the mint for signing. + */ + blindedMessages: Array; + /** + * secrets, kept client side for constructing proofs later. + */ + secrets: Array; + /** + * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. + */ + rs: Array; +}; + +/** + * Data that the library needs to hold in memory while it awaits the blinded signatures for the mint. It is later used for unblinding the signatures. + */ +export type BlindedTransaction = { + /** + * Blinded messages sent to the mint for signing. + */ + blindedMessages: Array; + /** + * secrets, kept client side for constructing proofs later. + */ + secrets: Array; + /** + * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. + */ + rs: Array; + /** + * amounts denominated in Satoshi + */ + amounts: Array; +}; + +/** + * Payload that needs to be sent to the mint when melting. Includes Return for overpaid fees + */ +export type MeltPayload = { + /** + * ID of the melt quote + */ + quote: string; + /** + * Inputs (Proofs) to be melted + */ + inputs: Array; + /** + * Blank outputs (blinded messages) that can be filled by the mint to return overpaid fees + */ + outputs: Array; +}; + +/** + * Payload that needs to be send to the mint to request a melt quote + */ +export type MeltQuotePayload = { + /** + * Unit to be melted + */ + unit: string; + /** + * Request to be melted to + */ + request: string; +}; + +/** + * Payload that needs to be sent to the mint when requesting a mint + */ +export type MintPayload = { + /** + * Quote ID received from the mint. + */ + quote: string; + /** + * Outputs (blinded messages) to be signed by the mint. + */ + outputs: Array; +}; + +/** + * Payload that needs to be sent to the mint when requesting a mint + */ +export type MintQuotePayload = { + /** + * Unit to be minted + */ + unit: string; + /** + * Amount to be minted + */ + amount: number; +}; + +/** + * Payload that needs to be sent to the mint when performing a split action + */ +export type SwapPayload = { + /** + * Inputs to the split operation + */ + inputs: Array; + /** + * Outputs (blinded messages) to be signed by the mint + */ + outputs: Array; +}; + +/** + * blinded message for sending to the mint + */ +export type SerializedBlindedMessage = { + /** + * amount + */ + amount: number; + /** + * Blinded message + */ + B_: string; + /** + * Keyset id + */ + id: string; +}; diff --git a/src/model/types/wallet/responses.ts b/src/model/types/wallet/responses.ts new file mode 100644 index 000000000..80fee56ae --- /dev/null +++ b/src/model/types/wallet/responses.ts @@ -0,0 +1,47 @@ +import {Proof, Token} from "./index"; + +/** + * Response after paying a Lightning invoice + */ +export type MeltTokensResponse = { + /** + * if false, the proofs have not been invalidated and the payment can be tried later again with the same proofs + */ + isPaid: boolean; + /** + * preimage of the paid invoice. can be null, depending on which LN-backend the mint uses + */ + preimage: string | null; + /** + * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate + */ + change: Array; +}; + +/** + * Response when receiving a complete token. + */ +export type ReceiveResponse = { + /** + * Successfully received Cashu Token + */ + token: Token; + /** + * TokenEntries that had errors. No error will be thrown, but clients can choose to handle tokens with errors accordingly. + */ + tokensWithErrors: Token | undefined; +}; + +/** + * response after sending + */ +export type SendResponse = { + /** + * Proofs that exceeded the needed amount + */ + returnChange: Array; + /** + * Proofs to be sent, matching the chosen amount + */ + send: Array; +}; diff --git a/src/model/types/wallet/tokens.ts b/src/model/types/wallet/tokens.ts new file mode 100644 index 000000000..3e1a30f98 --- /dev/null +++ b/src/model/types/wallet/tokens.ts @@ -0,0 +1,32 @@ +import {Proof} from "./index"; + +/** + * A Cashu token + */ +export type Token = { + /** + * token entries + */ + token: Array; + /** + * a message to send along with the token + */ + memo?: string; + /** + * the unit of the token + */ + unit?: string; +}; +/** + * TokenEntry that stores proofs and mints + */ +export type TokenEntry = { + /** + * a list of proofs + */ + proofs: Array; + /** + * the mints URL + */ + mint: string; +}; From 8be0932b303dc696afbbc6e659574d7c68beb780 Mon Sep 17 00:00:00 2001 From: Caleb Beery Date: Wed, 17 Jul 2024 18:42:59 -0700 Subject: [PATCH 25/39] Ran npm run format --- src/model/types/index.ts | 4 +- src/model/types/mint/index.ts | 16 +- src/model/types/mint/keys.ts | 64 +++---- src/model/types/mint/responses.ts | 272 ++++++++++++++-------------- src/model/types/wallet/index.ts | 72 ++++---- src/model/types/wallet/payloads.ts | 170 ++++++++--------- src/model/types/wallet/responses.ts | 58 +++--- src/model/types/wallet/tokens.ts | 42 ++--- 8 files changed, 348 insertions(+), 350 deletions(-) diff --git a/src/model/types/index.ts b/src/model/types/index.ts index b409e7ea3..0a73e886e 100644 --- a/src/model/types/index.ts +++ b/src/model/types/index.ts @@ -1,5 +1,5 @@ -export * from "./mint/index" -export * from "./wallet/index" +export * from './mint/index'; +export * from './wallet/index'; export type InvoiceData = { paymentRequest: string; diff --git a/src/model/types/mint/index.ts b/src/model/types/mint/index.ts index 79a5786fe..7fd9b8f3f 100644 --- a/src/model/types/mint/index.ts +++ b/src/model/types/mint/index.ts @@ -1,21 +1,21 @@ -import {SerializedBlindedMessage} from "../wallet"; +import { SerializedBlindedMessage } from '../wallet'; -export * from "./responses" -export * from "./keys" +export * from './responses'; +export * from './keys'; /** * Payload that needs to be sent to the mint when checking for spendable proofs */ export type CheckStatePayload = { - /** - * The Y = hash_to_curve(secret) of the proofs to be checked. - */ - Ys: Array; + /** + * The Y = hash_to_curve(secret) of the proofs to be checked. + */ + Ys: Array; }; /** * Request to mint at /v1/restore endpoint */ export type PostRestorePayload = { - outputs: Array; + outputs: Array; }; diff --git a/src/model/types/mint/keys.ts b/src/model/types/mint/keys.ts index 38c1905ce..c9ab3b905 100644 --- a/src/model/types/mint/keys.ts +++ b/src/model/types/mint/keys.ts @@ -7,54 +7,54 @@ export type Keys = { [amount: number]: string }; * An array of mint keysets */ export type MintActiveKeys = { - /** - * Keysets - */ - keysets: Array; + /** + * Keysets + */ + keysets: Array; }; /** * An array of mint keyset entries. */ export type MintAllKeysets = { - /** - * Keysets - */ - keysets: Array; + /** + * Keysets + */ + keysets: Array; }; /** * A mint keyset. */ export type MintKeys = { - /** - * Keyset ID - */ - id: string; - /** - * Unit of the keyset. - */ - unit: string; - /** - * Public keys are a dictionary of number and string. The number represents the amount that the key signs for. - */ - keys: Keys; + /** + * Keyset ID + */ + id: string; + /** + * Unit of the keyset. + */ + unit: string; + /** + * Public keys are a dictionary of number and string. The number represents the amount that the key signs for. + */ + keys: Keys; }; /** * A mint keyset entry. */ export type MintKeyset = { - /** - * Keyset ID - */ - id: string; - /** - * Unit of the keyset. - */ - unit: string; - /** - * Whether the keyset is active or not. - */ - active: boolean; + /** + * Keyset ID + */ + id: string; + /** + * Unit of the keyset. + */ + unit: string; + /** + * Whether the keyset is active or not. + */ + active: boolean; }; diff --git a/src/model/types/mint/responses.ts b/src/model/types/mint/responses.ts index 5c91058f9..9f42b9354 100644 --- a/src/model/types/mint/responses.ts +++ b/src/model/types/mint/responses.ts @@ -1,217 +1,217 @@ -import {SerializedBlindedMessage} from "../wallet"; +import { SerializedBlindedMessage } from '../wallet'; /** * Cashu api error */ export type ApiError = { - /** - * Error message - */ - error?: string; - /** - * HTTP error code - */ - code?: number; - /** - * Detailed error message - */ - detail?: string; + /** + * Error message + */ + error?: string; + /** + * HTTP error code + */ + code?: number; + /** + * Detailed error message + */ + detail?: string; }; /** * Entries of CheckStateResponse with state of the proof */ export type CheckStateEntry = { - Y: string; - state: CheckStateEnum; - witness: string | null; + Y: string; + state: CheckStateEnum; + witness: string | null; }; /** * Enum for the state of a proof */ export enum CheckStateEnum { - UNSPENT = 'UNSPENT', - PENDING = 'PENDING', - SPENT = 'SPENT' + UNSPENT = 'UNSPENT', + PENDING = 'PENDING', + SPENT = 'SPENT' } /** * Response when checking proofs if they are spendable. Should not rely on this for receiving, since it can be easily cheated. */ export type CheckStateResponse = { - /** - * - */ - states: Array; + /** + * + */ + states: Array; } & ApiError; /** * Response from mint at /info endpoint */ export type GetInfoResponse = { - name: string; - pubkey: string; - version: string; - description?: string; - description_long?: string; - contact: Array; - nuts: { - '4': { - methods: Array; - disabled: boolean; - }; - '5': { - methods: Array; - disabled: boolean; - }; - '7'?: { - supported: boolean; - }; - '8'?: { - supported: boolean; - }; - '9'?: { - supported: boolean; - }; - '10'?: { - supported: boolean; - }; - '11'?: { - supported: boolean; - }; - '12'?: { - supported: boolean; - }; - '13'?: { - supported: boolean; - }; - }; - motd?: string; + name: string; + pubkey: string; + version: string; + description?: string; + description_long?: string; + contact: Array; + nuts: { + '4': { + methods: Array; + disabled: boolean; + }; + '5': { + methods: Array; + disabled: boolean; + }; + '7'?: { + supported: boolean; + }; + '8'?: { + supported: boolean; + }; + '9'?: { + supported: boolean; + }; + '10'?: { + supported: boolean; + }; + '11'?: { + supported: boolean; + }; + '12'?: { + supported: boolean; + }; + '13'?: { + supported: boolean; + }; + }; + motd?: string; }; /** * Response from the mint after requesting a melt quote */ export type MeltQuoteResponse = { - /** - * Quote ID - */ - quote: string; - /** - * Amount to be melted - */ - amount: number; - /** - * Fee reserve to be added to the amount - */ - fee_reserve: number; - /** - * State of the melt quote - */ - state: MeltQuoteState; - /** - * Timestamp of when the quote expires - */ - expiry: number; - /** - * preimage of the paid invoice. is null if it the invoice has not been paid yet. can be null, depending on which LN-backend the mint uses - */ - payment_preimage: string | null; - /** - * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate - */ - change?: Array; + /** + * Quote ID + */ + quote: string; + /** + * Amount to be melted + */ + amount: number; + /** + * Fee reserve to be added to the amount + */ + fee_reserve: number; + /** + * State of the melt quote + */ + state: MeltQuoteState; + /** + * Timestamp of when the quote expires + */ + expiry: number; + /** + * preimage of the paid invoice. is null if it the invoice has not been paid yet. can be null, depending on which LN-backend the mint uses + */ + payment_preimage: string | null; + /** + * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate + */ + change?: Array; } & ApiError; export enum MeltQuoteState { - UNPAID = 'UNPAID', - PENDING = 'PENDING', - PAID = 'PAID' + UNPAID = 'UNPAID', + PENDING = 'PENDING', + PAID = 'PAID' } export type MintContactInfo = { - method: string; - info: string; + method: string; + info: string; }; export enum MintQuoteState { - UNPAID = 'UNPAID', - PAID = 'PAID', - ISSUED = 'ISSUED' + UNPAID = 'UNPAID', + PAID = 'PAID', + ISSUED = 'ISSUED' } /** * Response from the mint after requesting a mint */ export type MintQuoteResponse = { - /** - * Payment request - */ - request: string; - /** - * Quote ID - */ - quote: string; - /** - * State of the mint quote - */ - state: MintQuoteState; - /** - * Timestamp of when the quote expires - */ - expiry: number; + /** + * Payment request + */ + request: string; + /** + * Quote ID + */ + quote: string; + /** + * State of the mint quote + */ + state: MintQuoteState; + /** + * Timestamp of when the quote expires + */ + expiry: number; } & ApiError; /** * Response from the mint after requesting a mint */ export type MintResponse = { - signatures: Array; + signatures: Array; } & ApiError; /** * Response from mint at /v1/restore endpoint */ export type PostRestoreResponse = { - outputs: Array; - promises: Array; + outputs: Array; + promises: Array; }; /** * Blinded signature as it is received from the mint */ export type SerializedBlindedSignature = { - /** - * keyset id for indicating which public key was used to sign the blinded message - */ - id: string; - /** - * Amount denominated in Satoshi - */ - amount: number; - /** - * Blinded signature - */ - C_: string; + /** + * keyset id for indicating which public key was used to sign the blinded message + */ + id: string; + /** + * Amount denominated in Satoshi + */ + amount: number; + /** + * Blinded signature + */ + C_: string; }; /** * Ecash to other MoE swap method, displayed in @type {GetInfoResponse} */ export type SwapMethod = { - method: string; - unit: string; - min_amount: number; - max_amount: number; + method: string; + unit: string; + min_amount: number; + max_amount: number; }; /** * Response from the mint after performing a split action */ export type SwapResponse = { - /** - * represents the outputs after the split - */ - signatures: Array; + /** + * represents the outputs after the split + */ + signatures: Array; } & ApiError; diff --git a/src/model/types/wallet/index.ts b/src/model/types/wallet/index.ts index c14b10c9b..93c085fca 100644 --- a/src/model/types/wallet/index.ts +++ b/src/model/types/wallet/index.ts @@ -1,65 +1,63 @@ -export * from "./payloads" -export * from "./responses" -export * from "./tokens" +export * from './payloads'; +export * from './responses'; +export * from './tokens'; export type AmountPreference = { - amount: number; - count: number; + amount: number; + count: number; }; /** * represents a single Cashu proof. */ export type Proof = { - /** - * Keyset id, used to link proofs to a mint an its MintKeys. - */ - id: string; - /** - * Amount denominated in Satoshis. Has to match the amount of the mints signing key. - */ - amount: number; - /** - * The initial secret that was (randomly) chosen for the creation of this proof. - */ - secret: string; - /** - * The unblinded signature for this secret, signed by the mints private key. - */ - C: string; + /** + * Keyset id, used to link proofs to a mint an its MintKeys. + */ + id: string; + /** + * Amount denominated in Satoshis. Has to match the amount of the mints signing key. + */ + amount: number; + /** + * The initial secret that was (randomly) chosen for the creation of this proof. + */ + secret: string; + /** + * The unblinded signature for this secret, signed by the mints private key. + */ + C: string; }; /** * response when after receiving a single TokenEntry */ export type ReceiveTokenEntryResponse = { - /** - * Received proofs - */ - proofs: Array; + /** + * Received proofs + */ + proofs: Array; }; - /** * Payload that needs to be sent to the mint when paying a lightning invoice. */ export type PaymentPayload = { - /** - * Payment request/Lighting invoice that should get paid by the mint. - */ - pr: string; - /** - * Proofs, matching Lightning invoices amount + fees. - */ - proofs: Array; + /** + * Payment request/Lighting invoice that should get paid by the mint. + */ + pr: string; + /** + * Proofs, matching Lightning invoices amount + fees. + */ + proofs: Array; }; - /** * @deprecated Token V2 * should no longer be used */ export type TokenV2 = { - proofs: Array; - mints: Array<{ url: string; ids: Array }>; + proofs: Array; + mints: Array<{ url: string; ids: Array }>; }; diff --git a/src/model/types/wallet/payloads.ts b/src/model/types/wallet/payloads.ts index 73021cd7b..43539a91f 100644 --- a/src/model/types/wallet/payloads.ts +++ b/src/model/types/wallet/payloads.ts @@ -1,133 +1,133 @@ -import {Proof} from "./index"; +import { Proof } from './index'; /** * Data that the library needs to hold in memory while it awaits the blinded signatures for the mint. It is later used for unblinding the signatures. */ export type BlindedMessageData = { - /** - * Blinded messages sent to the mint for signing. - */ - blindedMessages: Array; - /** - * secrets, kept client side for constructing proofs later. - */ - secrets: Array; - /** - * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. - */ - rs: Array; + /** + * Blinded messages sent to the mint for signing. + */ + blindedMessages: Array; + /** + * secrets, kept client side for constructing proofs later. + */ + secrets: Array; + /** + * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. + */ + rs: Array; }; /** * Data that the library needs to hold in memory while it awaits the blinded signatures for the mint. It is later used for unblinding the signatures. */ export type BlindedTransaction = { - /** - * Blinded messages sent to the mint for signing. - */ - blindedMessages: Array; - /** - * secrets, kept client side for constructing proofs later. - */ - secrets: Array; - /** - * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. - */ - rs: Array; - /** - * amounts denominated in Satoshi - */ - amounts: Array; + /** + * Blinded messages sent to the mint for signing. + */ + blindedMessages: Array; + /** + * secrets, kept client side for constructing proofs later. + */ + secrets: Array; + /** + * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. + */ + rs: Array; + /** + * amounts denominated in Satoshi + */ + amounts: Array; }; /** * Payload that needs to be sent to the mint when melting. Includes Return for overpaid fees */ export type MeltPayload = { - /** - * ID of the melt quote - */ - quote: string; - /** - * Inputs (Proofs) to be melted - */ - inputs: Array; - /** - * Blank outputs (blinded messages) that can be filled by the mint to return overpaid fees - */ - outputs: Array; + /** + * ID of the melt quote + */ + quote: string; + /** + * Inputs (Proofs) to be melted + */ + inputs: Array; + /** + * Blank outputs (blinded messages) that can be filled by the mint to return overpaid fees + */ + outputs: Array; }; /** * Payload that needs to be send to the mint to request a melt quote */ export type MeltQuotePayload = { - /** - * Unit to be melted - */ - unit: string; - /** - * Request to be melted to - */ - request: string; + /** + * Unit to be melted + */ + unit: string; + /** + * Request to be melted to + */ + request: string; }; /** * Payload that needs to be sent to the mint when requesting a mint */ export type MintPayload = { - /** - * Quote ID received from the mint. - */ - quote: string; - /** - * Outputs (blinded messages) to be signed by the mint. - */ - outputs: Array; + /** + * Quote ID received from the mint. + */ + quote: string; + /** + * Outputs (blinded messages) to be signed by the mint. + */ + outputs: Array; }; /** * Payload that needs to be sent to the mint when requesting a mint */ export type MintQuotePayload = { - /** - * Unit to be minted - */ - unit: string; - /** - * Amount to be minted - */ - amount: number; + /** + * Unit to be minted + */ + unit: string; + /** + * Amount to be minted + */ + amount: number; }; /** * Payload that needs to be sent to the mint when performing a split action */ export type SwapPayload = { - /** - * Inputs to the split operation - */ - inputs: Array; - /** - * Outputs (blinded messages) to be signed by the mint - */ - outputs: Array; + /** + * Inputs to the split operation + */ + inputs: Array; + /** + * Outputs (blinded messages) to be signed by the mint + */ + outputs: Array; }; /** * blinded message for sending to the mint */ export type SerializedBlindedMessage = { - /** - * amount - */ - amount: number; - /** - * Blinded message - */ - B_: string; - /** - * Keyset id - */ - id: string; + /** + * amount + */ + amount: number; + /** + * Blinded message + */ + B_: string; + /** + * Keyset id + */ + id: string; }; diff --git a/src/model/types/wallet/responses.ts b/src/model/types/wallet/responses.ts index 80fee56ae..957b90f06 100644 --- a/src/model/types/wallet/responses.ts +++ b/src/model/types/wallet/responses.ts @@ -1,47 +1,47 @@ -import {Proof, Token} from "./index"; +import { Proof, Token } from './index'; /** * Response after paying a Lightning invoice */ export type MeltTokensResponse = { - /** - * if false, the proofs have not been invalidated and the payment can be tried later again with the same proofs - */ - isPaid: boolean; - /** - * preimage of the paid invoice. can be null, depending on which LN-backend the mint uses - */ - preimage: string | null; - /** - * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate - */ - change: Array; + /** + * if false, the proofs have not been invalidated and the payment can be tried later again with the same proofs + */ + isPaid: boolean; + /** + * preimage of the paid invoice. can be null, depending on which LN-backend the mint uses + */ + preimage: string | null; + /** + * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate + */ + change: Array; }; /** * Response when receiving a complete token. */ export type ReceiveResponse = { - /** - * Successfully received Cashu Token - */ - token: Token; - /** - * TokenEntries that had errors. No error will be thrown, but clients can choose to handle tokens with errors accordingly. - */ - tokensWithErrors: Token | undefined; + /** + * Successfully received Cashu Token + */ + token: Token; + /** + * TokenEntries that had errors. No error will be thrown, but clients can choose to handle tokens with errors accordingly. + */ + tokensWithErrors: Token | undefined; }; /** * response after sending */ export type SendResponse = { - /** - * Proofs that exceeded the needed amount - */ - returnChange: Array; - /** - * Proofs to be sent, matching the chosen amount - */ - send: Array; + /** + * Proofs that exceeded the needed amount + */ + returnChange: Array; + /** + * Proofs to be sent, matching the chosen amount + */ + send: Array; }; diff --git a/src/model/types/wallet/tokens.ts b/src/model/types/wallet/tokens.ts index 3e1a30f98..864695cf4 100644 --- a/src/model/types/wallet/tokens.ts +++ b/src/model/types/wallet/tokens.ts @@ -1,32 +1,32 @@ -import {Proof} from "./index"; +import { Proof } from './index'; /** * A Cashu token */ export type Token = { - /** - * token entries - */ - token: Array; - /** - * a message to send along with the token - */ - memo?: string; - /** - * the unit of the token - */ - unit?: string; + /** + * token entries + */ + token: Array; + /** + * a message to send along with the token + */ + memo?: string; + /** + * the unit of the token + */ + unit?: string; }; /** * TokenEntry that stores proofs and mints */ export type TokenEntry = { - /** - * a list of proofs - */ - proofs: Array; - /** - * the mints URL - */ - mint: string; + /** + * a list of proofs + */ + proofs: Array; + /** + * the mints URL + */ + mint: string; }; From 9a8d59c8e34d3aa1f550bcc6dd1523713a460d57 Mon Sep 17 00:00:00 2001 From: Egge Date: Tue, 13 Aug 2024 10:15:44 +0200 Subject: [PATCH 26/39] moved v4 token types --- src/model/types/index.ts | 18 ----------- src/model/types/wallet/tokens.ts | 54 ++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/model/types/index.ts b/src/model/types/index.ts index 0a73e886e..d0032a879 100644 --- a/src/model/types/index.ts +++ b/src/model/types/index.ts @@ -10,21 +10,3 @@ export type InvoiceData = { memo?: string; expiry?: number; }; - -export type V4ProofTemplate = { - a: number; - s: string; - c: Uint8Array; -}; - -export type V4InnerToken = { - i: Uint8Array; - p: Array; -}; - -export type TokenV4Template = { - t: Array; - d: string; - m: string; - u: string; -}; diff --git a/src/model/types/wallet/tokens.ts b/src/model/types/wallet/tokens.ts index 864695cf4..636fe039d 100644 --- a/src/model/types/wallet/tokens.ts +++ b/src/model/types/wallet/tokens.ts @@ -30,3 +30,57 @@ export type TokenEntry = { */ mint: string; }; + +/** + * Template for a Proof inside a V4 Token + */ +export type V4ProofTemplate = { + /** + * Amount + */ + a: number; + /** + * Secret + */ + s: string; + /** + * Signature + */ + c: Uint8Array; +}; + +/** + * TokenEntry in a V4 Token + */ +export type V4InnerToken = { + /** + * ID + */ + i: Uint8Array; + /** + * Proofs + */ + p: Array; +}; + +/** + * Template for a V4 Token + */ +export type TokenV4Template = { + /** + * TokenEntries + */ + t: Array; + /** + * Memo + */ + d: string; + /** + * Mint Url + */ + m: string; + /** + * Unit + */ + u: string; +}; From d3dec5bd2507da89be78f6dd02bf148f2a453940 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Sat, 17 Aug 2024 23:30:49 +0200 Subject: [PATCH 27/39] add token v4 to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8c4137966..1e1e6ca99 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ Supported token formats: - [x] v1 read - [x] v2 read (deprecated) - [x] v3 read/write +- [x] v4 read/write ## Usage From 404730997d955b58c4c7bde26377322e8742c983 Mon Sep 17 00:00:00 2001 From: Alex Lewin Date: Fri, 23 Aug 2024 13:13:33 -0400 Subject: [PATCH 28/39] feat: imporved typesafety for decode cbor functions --- src/cbor.ts | 80 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/src/cbor.ts b/src/cbor.ts index 0436ff747..07b8a7bea 100644 --- a/src/cbor.ts +++ b/src/cbor.ts @@ -1,3 +1,26 @@ +type SimpleValue = boolean | null | undefined; + +export type ResultObject = { [key: string]: ResultValue }; +export type ResultValue = + | SimpleValue + | number + | string + | Uint8Array + | Array + | ResultObject; + +type ResultKeyType = Extract; +export type ValidDecodedType = Extract; + +function isResultKeyType(value: ResultValue): value is ResultKeyType { + return typeof value === 'number' || typeof value === 'string'; +} + +type DecodeResult = { + value: T; + offset: number; +}; + export function encodeCBOR(value: any) { const buffer: Array = []; encodeItem(value, buffer); @@ -119,18 +142,14 @@ function encodeObject(value: { [key: string]: any }, buffer: Array) { encodeItem(value[key], buffer); } } -type DecodeResult = { - value: any; - offset: number; -}; -export function decodeCBOR(data: Uint8Array): any { +export function decodeCBOR(data: Uint8Array): ResultValue { const view = new DataView(data.buffer, data.byteOffset, data.byteLength); const result = decodeItem(view, 0); return result.value; } -function decodeItem(view: DataView, offset: number): DecodeResult { +function decodeItem(view: DataView, offset: number): DecodeResult { if (offset >= view.byteLength) { throw new Error('Unexpected end of data'); } @@ -158,7 +177,11 @@ function decodeItem(view: DataView, offset: number): DecodeResult { } } -function decodeLength(view: DataView, offset: number, additionalInfo: number): DecodeResult { +function decodeLength( + view: DataView, + offset: number, + additionalInfo: number +): DecodeResult { if (additionalInfo < 24) return { value: additionalInfo, offset }; if (additionalInfo === 24) return { value: view.getUint8(offset++), offset }; if (additionalInfo === 25) { @@ -180,17 +203,29 @@ function decodeLength(view: DataView, offset: number, additionalInfo: number): D throw new Error(`Unsupported length: ${additionalInfo}`); } -function decodeUnsigned(view: DataView, offset: number, additionalInfo: number): DecodeResult { +function decodeUnsigned( + view: DataView, + offset: number, + additionalInfo: number +): DecodeResult { const { value, offset: newOffset } = decodeLength(view, offset, additionalInfo); return { value, offset: newOffset }; } -function decodeSigned(view: DataView, offset: number, additionalInfo: number): DecodeResult { +function decodeSigned( + view: DataView, + offset: number, + additionalInfo: number +): DecodeResult { const { value, offset: newOffset } = decodeLength(view, offset, additionalInfo); return { value: -1 - value, offset: newOffset }; } -function decodeByteString(view: DataView, offset: number, additionalInfo: number): DecodeResult { +function decodeByteString( + view: DataView, + offset: number, + additionalInfo: number +): DecodeResult { const { value: length, offset: newOffset } = decodeLength(view, offset, additionalInfo); if (newOffset + length > view.byteLength) { throw new Error('Byte string length exceeds data length'); @@ -199,7 +234,11 @@ function decodeByteString(view: DataView, offset: number, additionalInfo: number return { value, offset: newOffset + length }; } -function decodeString(view: DataView, offset: number, additionalInfo: number): DecodeResult { +function decodeString( + view: DataView, + offset: number, + additionalInfo: number +): DecodeResult { const { value: length, offset: newOffset } = decodeLength(view, offset, additionalInfo); if (newOffset + length > view.byteLength) { throw new Error('String length exceeds data length'); @@ -209,7 +248,11 @@ function decodeString(view: DataView, offset: number, additionalInfo: number): D return { value, offset: newOffset + length }; } -function decodeArray(view: DataView, offset: number, additionalInfo: number): DecodeResult { +function decodeArray( + view: DataView, + offset: number, + additionalInfo: number +): DecodeResult> { const { value: length, offset: newOffset } = decodeLength(view, offset, additionalInfo); const array = []; let currentOffset = newOffset; @@ -221,12 +264,19 @@ function decodeArray(view: DataView, offset: number, additionalInfo: number): De return { value: array, offset: currentOffset }; } -function decodeMap(view: DataView, offset: number, additionalInfo: number): DecodeResult { +function decodeMap( + view: DataView, + offset: number, + additionalInfo: number +): DecodeResult> { const { value: length, offset: newOffset } = decodeLength(view, offset, additionalInfo); - const map: { [key: string]: any } = {}; + const map: { [key: string]: ResultValue } = {}; let currentOffset = newOffset; for (let i = 0; i < length; i++) { const keyResult = decodeItem(view, currentOffset); + if (!isResultKeyType(keyResult.value)) { + throw new Error('Invalid key type'); + } const valueResult = decodeItem(view, keyResult.offset); map[keyResult.value] = valueResult.value; currentOffset = valueResult.offset; @@ -251,7 +301,7 @@ function decodeSimpleAndFloat( view: DataView, offset: number, additionalInfo: number -): DecodeResult { +): DecodeResult { if (additionalInfo < 24) { switch (additionalInfo) { case 20: From e652f592a3d111b059d20dc5e9de35f76888e05c Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Tue, 27 Aug 2024 23:20:11 +0200 Subject: [PATCH 29/39] fix base64 url --- src/base64.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/base64.ts b/src/base64.ts index 266bb7d4a..c30f2b9ef 100644 --- a/src/base64.ts +++ b/src/base64.ts @@ -5,7 +5,10 @@ function encodeUint8toBase64(uint8array: Uint8Array): string { } function encodeUint8toBase64Url(bytes: Uint8Array): string { - return Buffer.from(bytes).toString('base64url').replace(/\=+$/, ''); + return Buffer.from(bytes).toString('base64') + .replace(/\+/g, '-') // Replace + with - + .replace(/\//g, '_') // Replace / with _ + .replace(/=+$/, ''); // Remove padding characters } function encodeBase64toUint8(base64String: string): Uint8Array { From 44015430e12fdbd637187d5066ba48b5dcdc8c6d Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Wed, 28 Aug 2024 13:28:23 +0200 Subject: [PATCH 30/39] npm run format --- src/base64.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/base64.ts b/src/base64.ts index c30f2b9ef..18f19b99f 100644 --- a/src/base64.ts +++ b/src/base64.ts @@ -5,10 +5,11 @@ function encodeUint8toBase64(uint8array: Uint8Array): string { } function encodeUint8toBase64Url(bytes: Uint8Array): string { - return Buffer.from(bytes).toString('base64') - .replace(/\+/g, '-') // Replace + with - - .replace(/\//g, '_') // Replace / with _ - .replace(/=+$/, ''); // Remove padding characters + return Buffer.from(bytes) + .toString('base64') + .replace(/\+/g, '-') // Replace + with - + .replace(/\//g, '_') // Replace / with _ + .replace(/=+$/, ''); // Remove padding characters } function encodeBase64toUint8(base64String: string): Uint8Array { From 5548d7efcb4372740c5f3501ecd2be90770794f5 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Wed, 28 Aug 2024 13:31:01 +0200 Subject: [PATCH 31/39] bump cashu/crypto to 0.2.7 --- package-lock.json | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 109d21187..70f70b4e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.1.0-1", "license": "MIT", "dependencies": { - "@cashu/crypto": "^0.2.6", + "@cashu/crypto": "^0.2.7", "@noble/curves": "^1.3.0", "@noble/hashes": "^1.3.3", "@scure/bip32": "^1.3.3", @@ -624,6 +624,7 @@ "version": "0.2.7", "resolved": "https://registry.npmjs.org/@cashu/crypto/-/crypto-0.2.7.tgz", "integrity": "sha512-1aaDfUjiHNXoJqg8nW+341TLWV9W28DsVNXJUKcHL0yAmwLs5+56SSnb8LLDJzPamLVoYL0U0bda91klAzptig==", + "license": "MIT", "dependencies": { "@noble/curves": "^1.3.0", "@noble/hashes": "^1.3.3", diff --git a/package.json b/package.json index a04b15dbb..2e25d8415 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "typescript": "^5.0.4" }, "dependencies": { - "@cashu/crypto": "^0.2.6", + "@cashu/crypto": "^0.2.7", "@noble/curves": "^1.3.0", "@noble/hashes": "^1.3.3", "@scure/bip32": "^1.3.3", From 38910359cc2336029c8cdca4e2ac906a5d8ac96e Mon Sep 17 00:00:00 2001 From: Egge Date: Wed, 28 Aug 2024 13:47:18 +0200 Subject: [PATCH 32/39] bumped version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 70f70b4e0..627f68038 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cashu/cashu-ts", - "version": "1.1.0-1", + "version": "1.1.0-2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@cashu/cashu-ts", - "version": "1.1.0-1", + "version": "1.1.0-2", "license": "MIT", "dependencies": { "@cashu/crypto": "^0.2.7", diff --git a/package.json b/package.json index 2e25d8415..effb18185 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cashu/cashu-ts", - "version": "1.1.0-1", + "version": "1.1.0-2", "description": "cashu library for communicating with a cashu mint", "main": "dist/lib/es5/index.js", "module": "dist/lib/es6/index.js", From c7f463747583239616349d03aa97110ceb83d034 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 30 Aug 2024 00:19:56 +0200 Subject: [PATCH 33/39] propagate errors (integration test not fixed yet) --- src/CashuWallet.ts | 74 ++++++++++++++++++++------------------------- test/wallet.test.ts | 4 +-- 2 files changed, 35 insertions(+), 43 deletions(-) diff --git a/src/CashuWallet.ts b/src/CashuWallet.ts index 23a31fae7..0442bb04e 100644 --- a/src/CashuWallet.ts +++ b/src/CashuWallet.ts @@ -130,22 +130,18 @@ class CashuWallet { privkey?: string; } ): Promise> { - try { - if (typeof token === 'string') { - token = getDecodedToken(token); - } - const tokenEntries: Array = token.token; - const proofs = await this.receiveTokenEntry(tokenEntries[0], { - keysetId: options?.keysetId, - preference: options?.preference, - counter: options?.counter, - pubkey: options?.pubkey, - privkey: options?.privkey - }); - return proofs; - } catch (error) { - throw new Error('Error when receiving'); + if (typeof token === 'string') { + token = getDecodedToken(token); } + const tokenEntries: Array = token.token; + const proofs = await this.receiveTokenEntry(tokenEntries[0], { + keysetId: options?.keysetId, + preference: options?.preference, + counter: options?.counter, + pubkey: options?.pubkey, + privkey: options?.privkey + }); + return proofs; } /** @@ -168,33 +164,29 @@ class CashuWallet { } ): Promise> { const proofs: Array = []; - try { - const amount = tokenEntry.proofs.reduce((total, curr) => total + curr.amount, 0); - let preference = options?.preference; - if (!preference) { - preference = getDefaultAmountPreference(amount); - } - const keys = await this.getKeys(options?.keysetId); - const { payload, blindedMessages } = this.createSwapPayload( - amount, - tokenEntry.proofs, - keys, - preference, - options?.counter, - options?.pubkey, - options?.privkey - ); - const { signatures } = await CashuMint.split(tokenEntry.mint, payload); - const newProofs = this.constructProofs( - signatures, - blindedMessages.rs, - blindedMessages.secrets, - keys - ); - proofs.push(...newProofs); - } catch (error) { - throw new Error('Error receiving token entry'); + const amount = tokenEntry.proofs.reduce((total, curr) => total + curr.amount, 0); + let preference = options?.preference; + if (!preference) { + preference = getDefaultAmountPreference(amount); } + const keys = await this.getKeys(options?.keysetId); + const { payload, blindedMessages } = this.createSwapPayload( + amount, + tokenEntry.proofs, + keys, + preference, + options?.counter, + options?.pubkey, + options?.privkey + ); + const { signatures } = await CashuMint.split(tokenEntry.mint, payload); + const newProofs = this.constructProofs( + signatures, + blindedMessages.rs, + blindedMessages.secrets, + keys + ); + proofs.push(...newProofs); return proofs; } diff --git a/test/wallet.test.ts b/test/wallet.test.ts index b8bd97d86..913c02c4a 100644 --- a/test/wallet.test.ts +++ b/test/wallet.test.ts @@ -180,14 +180,14 @@ describe('receive', () => { nock(mintUrl).post('/v1/swap').reply(400, { detail: msg }); const wallet = new CashuWallet(mint, { unit }); const result = await wallet.receive(tokenInput).catch((e) => e); - expect(result).toEqual(new Error('Error when receiving')); + expect(result).toEqual(new Error('tokens already spent. Secret: asdasdasd')); }); test('test receive could not verify proofs', async () => { nock(mintUrl).post('/v1/swap').reply(400, { code: 0, error: 'could not verify proofs.' }); const wallet = new CashuWallet(mint, { unit }); const result = await wallet.receive(tokenInput).catch((e) => e); - expect(result).toEqual(new Error('Error when receiving')); + expect(result).toEqual(new Error('could not verify proofs.')); }); }); From a53a62df8f00410a40bc52801ccff37bf41ac217 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 30 Aug 2024 00:21:34 +0200 Subject: [PATCH 34/39] fix integration test --- test/integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration.test.ts b/test/integration.test.ts index bb43f253d..2d069392d 100644 --- a/test/integration.test.ts +++ b/test/integration.test.ts @@ -203,7 +203,7 @@ describe('mint api', () => { const result = await wallet .receive(encoded, { privkey: bytesToHex(privKeyAlice) }) .catch((e) => e); - expect(result).toEqual(new Error('Error when receiving')); + expect(result).toEqual(new Error('no valid signature provided for input.')); const proofs = await wallet.receive(encoded, { privkey: bytesToHex(privKeyBob) }); From 4e4a5ad275537e80a529e30d80e952d337c68f92 Mon Sep 17 00:00:00 2001 From: Egge Date: Fri, 30 Aug 2024 08:34:32 +0200 Subject: [PATCH 35/39] bumped version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 627f68038..69d22b893 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cashu/cashu-ts", - "version": "1.1.0-2", + "version": "1.1.0-3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@cashu/cashu-ts", - "version": "1.1.0-2", + "version": "1.1.0-3", "license": "MIT", "dependencies": { "@cashu/crypto": "^0.2.7", diff --git a/package.json b/package.json index effb18185..5e33c1f35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cashu/cashu-ts", - "version": "1.1.0-2", + "version": "1.1.0-3", "description": "cashu library for communicating with a cashu mint", "main": "dist/lib/es5/index.js", "module": "dist/lib/es6/index.js", From f900f64aefe57dac7400f4ebd7c9d024bb3dd063 Mon Sep 17 00:00:00 2001 From: Egge Date: Sun, 8 Sep 2024 21:10:02 +0200 Subject: [PATCH 36/39] Prep Release v1.1.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 69d22b893..ea6b6cfe4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cashu/cashu-ts", - "version": "1.1.0-3", + "version": "1.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@cashu/cashu-ts", - "version": "1.1.0-3", + "version": "1.1.0", "license": "MIT", "dependencies": { "@cashu/crypto": "^0.2.7", diff --git a/package.json b/package.json index 5e33c1f35..ac89ee797 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cashu/cashu-ts", - "version": "1.1.0-3", + "version": "1.1.0", "description": "cashu library for communicating with a cashu mint", "main": "dist/lib/es5/index.js", "module": "dist/lib/es6/index.js", From c999b98686d0e348a0431d386721f0bf0acdb972 Mon Sep 17 00:00:00 2001 From: Egge Date: Sat, 19 Oct 2024 19:50:24 +0200 Subject: [PATCH 37/39] Merge Dev: v1.2.0-1 --- .eslintrc.json | 9 +- .github/workflows/nextVersion.yml | 24 +++++ .github/workflows/prerelease.yml | 21 +++++ package.json | 2 +- src/CashuMint.ts | 3 +- src/CashuWallet.ts | 103 +++++++++++++++------- src/index.ts | 11 ++- src/legacy/cashu-ts.ts | 23 +++++ src/model/PaymentRequest.ts | 76 ++++++++++++++++ src/model/types/index.ts | 7 ++ src/model/types/wallet/index.ts | 1 + src/model/types/wallet/payloads.ts | 4 + src/model/types/wallet/paymentRequests.ts | 36 ++++++++ src/utils.ts | 87 +++++++++++------- test/integration.test.ts | 30 +++++++ test/paymentRequests.test.ts | 65 ++++++++++++++ test/utils.test.ts | 57 +++++++++--- test/wallet.test.ts | 8 +- 18 files changed, 480 insertions(+), 87 deletions(-) create mode 100644 .github/workflows/nextVersion.yml create mode 100644 .github/workflows/prerelease.yml create mode 100644 src/legacy/cashu-ts.ts create mode 100644 src/model/PaymentRequest.ts create mode 100644 src/model/types/wallet/paymentRequests.ts create mode 100644 test/paymentRequests.test.ts diff --git a/.eslintrc.json b/.eslintrc.json index 35123f100..b74d1793e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,4 +1,3 @@ -// .eslintrc { "parser": "@typescript-eslint/parser", "parserOptions": { @@ -10,12 +9,12 @@ "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], "rules": { - "@typescript-eslint/no-unused-vars": "warn", - // to enforce using type for object type definitions, can be type or interface + "@typescript-eslint/no-unused-vars": "error", + "@typescript-eslint/typedef": ["error", { "parameter": true, "arrowParameter": true }], "@typescript-eslint/consistent-type-definitions": ["warn", "type"], - "@typescript-eslint/array-type": ["warn", { "default": "generic" }], + "@typescript-eslint/array-type": ["error", { "default": "generic" }], "require-await": "off", - "@typescript-eslint/require-await": "warn", + "@typescript-eslint/require-await": "error", "@typescript-eslint/await-thenable": "warn", "@typescript-eslint/consistent-type-exports": "warn", "no-else-return": "warn" diff --git a/.github/workflows/nextVersion.yml b/.github/workflows/nextVersion.yml new file mode 100644 index 000000000..964ce5baa --- /dev/null +++ b/.github/workflows/nextVersion.yml @@ -0,0 +1,24 @@ +name: Publish Package to npmjs +permissions: + contents: write + id-token: write +on: + push: + branches: + - staging +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v3 + with: + node-version: 20 + registry-url: 'https://registry.npmjs.org' + - run: npm i + - run: npm run compile + - run: npm version prerelease --preid=rc --no-git-tag-version + - run: git push + - run: npm publish --provenance --access public --tag next + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml new file mode 100644 index 000000000..a0ce67a4f --- /dev/null +++ b/.github/workflows/prerelease.yml @@ -0,0 +1,21 @@ +name: Publish Package to npmjs +permissions: + contents: read + id-token: write +on: + release: + types: [prereleased] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v3 + with: + node-version: 20 + registry-url: 'https://registry.npmjs.org' + - run: npm ci + - run: npm run compile + - run: npm publish --tag next --provenance + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/package.json b/package.json index ac89ee797..813c3ad00 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cashu/cashu-ts", - "version": "1.1.0", + "version": "1.2.0", "description": "cashu library for communicating with a cashu mint", "main": "dist/lib/es5/index.js", "module": "dist/lib/es6/index.js", diff --git a/src/CashuMint.ts b/src/CashuMint.ts index 3729ae028..8df76b83d 100644 --- a/src/CashuMint.ts +++ b/src/CashuMint.ts @@ -15,8 +15,7 @@ import type { MintResponse, PostRestorePayload, MeltQuotePayload, - MeltQuoteResponse, - MintContactInfo + MeltQuoteResponse } from './model/types/index.js'; import { MeltQuoteState } from './model/types/index.js'; import request from './request.js'; diff --git a/src/CashuWallet.ts b/src/CashuWallet.ts index 0442bb04e..6f8280ce7 100644 --- a/src/CashuWallet.ts +++ b/src/CashuWallet.ts @@ -20,7 +20,9 @@ import { type TokenEntry, CheckStateEnum, SerializedBlindedSignature, - MeltQuoteState + MeltQuoteState, + CheckStateEntry, + Preferences } from './model/types/index.js'; import { bytesToNumber, @@ -28,6 +30,7 @@ import { getDefaultAmountPreference, splitAmount } from './utils.js'; +import { isAmountPreferenceArray, deprecatedAmountPreferences } from './legacy/cashu-ts'; import { validateMnemonic } from '@scure/bip39'; import { wordlist } from '@scure/bip39/wordlists/english'; import { hashToCurve, pointFromHex } from '@cashu/crypto/modules/common'; @@ -164,17 +167,18 @@ class CashuWallet { } ): Promise> { const proofs: Array = []; - const amount = tokenEntry.proofs.reduce((total, curr) => total + curr.amount, 0); + const amount = tokenEntry.proofs.reduce((total: number, curr: Proof) => total + curr.amount, 0); let preference = options?.preference; + const keys = await this.getKeys(options?.keysetId); if (!preference) { - preference = getDefaultAmountPreference(amount); + preference = getDefaultAmountPreference(amount, keys); } - const keys = await this.getKeys(options?.keysetId); + const pref: Preferences = { sendPreference: preference }; const { payload, blindedMessages } = this.createSwapPayload( amount, tokenEntry.proofs, keys, - preference, + pref, options?.counter, options?.pubkey, options?.privkey @@ -206,7 +210,7 @@ class CashuWallet { amount: number, proofs: Array, options?: { - preference?: Array; + preference?: Preferences | Array; counter?: number; pubkey?: string; privkey?: string; @@ -214,13 +218,19 @@ class CashuWallet { } ): Promise { if (options?.preference) { - amount = options?.preference?.reduce((acc, curr) => acc + curr.amount * curr.count, 0); + if (isAmountPreferenceArray(options.preference)) { + options.preference = deprecatedAmountPreferences(options.preference); + } + amount = options?.preference?.sendPreference.reduce( + (acc: number, curr: AmountPreference) => acc + curr.amount * curr.count, + 0 + ); } const keyset = await this.getKeys(options?.keysetId); let amountAvailable = 0; const proofsToSend: Array = []; const proofsToKeep: Array = []; - proofs.forEach((proof) => { + proofs.forEach((proof: Proof) => { if (amountAvailable >= amount) { proofsToKeep.push(proof); return; @@ -254,7 +264,7 @@ class CashuWallet { const splitProofsToKeep: Array = []; const splitProofsToSend: Array = []; let amountKeepCounter = 0; - proofs.forEach((proof) => { + proofs.forEach((proof: Proof) => { if (amountKeepCounter < amountKeep) { amountKeepCounter += proof.amount; splitProofsToKeep.push(proof); @@ -294,9 +304,11 @@ class CashuWallet { const { outputs, promises } = await this.mint.restore({ outputs: blindedMessages }); // Collect and map the secrets and blinding factors with the blinded messages that were returned from the mint - const validRs = rs.filter((r, i) => outputs.map((o) => o.B_).includes(blindedMessages[i].B_)); - const validSecrets = secrets.filter((s, i) => - outputs.map((o) => o.B_).includes(blindedMessages[i].B_) + const validRs = rs.filter((_: bigint, i: number) => + outputs.map((o: SerializedBlindedMessage) => o.B_).includes(blindedMessages[i].B_) + ); + const validSecrets = secrets.filter((_: Uint8Array, i: number) => + outputs.map((o: SerializedBlindedMessage) => o.B_).includes(blindedMessages[i].B_) ); return { @@ -312,9 +324,9 @@ class CashuWallet { const allKeys = await this.mint.getKeys(keysetId); let keys; if (keysetId) { - keys = allKeys.keysets.find((k) => k.id === keysetId); + keys = allKeys.keysets.find((k: MintKeys) => k.id === keysetId); } else { - keys = allKeys.keysets.find((k) => (unit ? k.unit === unit : k.unit === 'sat')); + keys = allKeys.keysets.find((k: MintKeys) => (unit ? k.unit === unit : k.unit === 'sat')); } if (!keys) { throw new Error( @@ -331,12 +343,14 @@ class CashuWallet { /** * Requests a mint quote form the mint. Response returns a Lightning payment request for the requested given amount and unit. * @param amount Amount requesting for mint. + * @param description optional description for the mint quote * @returns the mint will return a mint quote with a Lightning invoice for minting tokens of the specified amount and unit */ - async createMintQuote(amount: number) { + async createMintQuote(amount: number, description?: string) { const mintQuotePayload: MintQuotePayload = { unit: this._unit, - amount: amount + amount: amount, + description: description }; return await this.mint.createMintQuote(mintQuotePayload); } @@ -369,7 +383,7 @@ class CashuWallet { const keyset = await this.getKeys(options?.keysetId); const { blindedMessages, secrets, rs } = this.createRandomBlindedMessages( amount, - options?.keysetId ?? keyset.id, + keyset, options?.preference, options?.counter, options?.pubkey @@ -415,6 +429,7 @@ class CashuWallet { * @param proofsToSend proofs to melt * @param options.keysetId? optionally set keysetId for blank outputs for returned change. * @param options.counter? optionally set counter to derive secret deterministically. CashuWallet class must be initialized with seed phrase to take effect + * @param options.privkey? optionally set a private key to unlock P2PK locked secrets * @returns */ async meltTokens( @@ -423,6 +438,7 @@ class CashuWallet { options?: { keysetId?: string; counter?: number; + privkey?: string; } ): Promise { const keys = await this.getKeys(options?.keysetId); @@ -432,6 +448,19 @@ class CashuWallet { keys.id, options?.counter ); + if (options?.privkey != undefined) { + proofsToSend = getSignedProofs( + proofsToSend.map((p: Proof) => { + return { + amount: p.amount, + C: pointFromHex(p.C), + id: p.id, + secret: new TextEncoder().encode(p.secret) + }; + }), + options.privkey + ).map((p: NUT11Proof) => serializeProof(p)); + } const meltPayload: MeltPayload = { quote: meltQuote.quote, inputs: proofsToSend, @@ -456,6 +485,7 @@ class CashuWallet { * @param meltQuote melt quote for the invoice * @param options.keysetId? optionally set keysetId for blank outputs for returned change. * @param options.counter? optionally set counter to derive secret deterministically. CashuWallet class must be initialized with seed phrase to take effect + * @param options.privkey? optionally set a private key to unlock P2PK locked secrets * @returns */ async payLnInvoice( @@ -465,6 +495,7 @@ class CashuWallet { options?: { keysetId?: string; counter?: number; + privkey?: string; } ): Promise { if (!meltQuote) { @@ -472,7 +503,8 @@ class CashuWallet { } return await this.meltTokens(meltQuote, proofsToSend, { keysetId: options?.keysetId, - counter: options?.counter + counter: options?.counter, + privkey: options?.privkey }); } @@ -495,8 +527,8 @@ class CashuWallet { ): Promise { const decodedToken = getDecodedToken(token); const proofs = decodedToken.token - .filter((x) => x.mint === this.mint.mintUrl) - .flatMap((t) => t.proofs); + .filter((x: TokenEntry) => x.mint === this.mint.mintUrl) + .flatMap((t: TokenEntry) => t.proofs); return this.payLnInvoice(invoice, proofs, meltQuote, { keysetId: options?.keysetId, counter: options?.counter @@ -517,7 +549,7 @@ class CashuWallet { amount: number, proofsToSend: Array, keyset: MintKeys, - preference?: Array, + preference?: Preferences | Array, counter?: number, pubkey?: string, privkey?: string @@ -525,11 +557,14 @@ class CashuWallet { payload: SwapPayload; blindedMessages: BlindedTransaction; } { - const totalAmount = proofsToSend.reduce((total, curr) => total + curr.amount, 0); + if (isAmountPreferenceArray(preference)) { + preference = deprecatedAmountPreferences(preference); + } + const totalAmount = proofsToSend.reduce((total: number, curr: Proof) => total + curr.amount, 0); const keepBlindedMessages = this.createRandomBlindedMessages( totalAmount - amount, - keyset.id, - undefined, + keyset, + preference?.keepPreference, counter ); if (this._seed && counter) { @@ -537,14 +572,14 @@ class CashuWallet { } const sendBlindedMessages = this.createRandomBlindedMessages( amount, - keyset.id, - preference, + keyset, + preference?.sendPreference, counter, pubkey ); if (privkey) { proofsToSend = getSignedProofs( - proofsToSend.map((p) => { + proofsToSend.map((p: Proof) => { return { amount: p.amount, C: pointFromHex(p.C), @@ -580,15 +615,15 @@ class CashuWallet { */ async checkProofsSpent(proofs: Array): Promise> { const enc = new TextEncoder(); - const Ys = proofs.map((p) => hashToCurve(enc.encode(p.secret)).toHex(true)); + const Ys = proofs.map((p: T) => hashToCurve(enc.encode(p.secret)).toHex(true)); const payload = { // array of Ys of proofs to check Ys: Ys }; const { states } = await this.mint.check(payload); - return proofs.filter((_, i) => { - const state = states.find((state) => state.Y === Ys[i]); + return proofs.filter((_: T, i: number) => { + const state = states.find((state: CheckStateEntry) => state.Y === Ys[i]); return state && state.state === CheckStateEnum.SPENT; }); } @@ -612,13 +647,13 @@ class CashuWallet { */ private createRandomBlindedMessages( amount: number, - keysetId: string, + keyset: MintKeys, amountPreference?: Array, counter?: number, pubkey?: string ): BlindedMessageData & { amounts: Array } { - const amounts = splitAmount(amount, amountPreference); - return this.createBlindedMessages(amounts, keysetId, counter, pubkey); + const amounts = splitAmount(amount, keyset.keys, amountPreference); + return this.createBlindedMessages(amounts, keyset.id, counter, pubkey); } /** @@ -713,7 +748,7 @@ class CashuWallet { const A = pointFromHex(keyset.keys[p.amount]); return constructProofFromPromise(blindSignature, r, secret, A); }) - .map((p) => serializeProof(p) as Proof); + .map((p: NUT11Proof) => serializeProof(p) as Proof); } } diff --git a/src/index.ts b/src/index.ts index 530629f13..c3cc1e06d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,26 @@ import { CashuMint } from './CashuMint.js'; import { CashuWallet } from './CashuWallet.js'; +import { PaymentRequest } from './model/PaymentRequest.js'; import { setGlobalRequestOptions } from './request.js'; import { generateNewMnemonic, deriveSeedFromMnemonic } from '@cashu/crypto/modules/client/NUT09'; -import { getEncodedToken, getEncodedTokenV4, getDecodedToken, deriveKeysetId } from './utils.js'; +import { + getEncodedToken, + getEncodedTokenV4, + getDecodedToken, + deriveKeysetId, + decodePaymentRequest +} from './utils.js'; export * from './model/types/index.js'; export { CashuMint, CashuWallet, + PaymentRequest, getDecodedToken, getEncodedToken, getEncodedTokenV4, + decodePaymentRequest, deriveKeysetId, generateNewMnemonic, deriveSeedFromMnemonic, diff --git a/src/legacy/cashu-ts.ts b/src/legacy/cashu-ts.ts new file mode 100644 index 000000000..056091456 --- /dev/null +++ b/src/legacy/cashu-ts.ts @@ -0,0 +1,23 @@ +import { AmountPreference, Preferences } from '../model/types/index'; + +export const deprecatedAmountPreferences = function (pref: Array): Preferences { + console.warn('[DEPRECATION] Use `Preferences` instead of `Array`'); + return { sendPreference: pref }; +}; + +export const isAmountPreference = function (obj: any): obj is AmountPreference { + return ( + typeof obj === 'object' && + obj !== null && + 'amount' in obj && + 'count' in obj && + typeof obj.amount === 'number' && + typeof obj.count === 'number' + ); +}; + +export const isAmountPreferenceArray = function ( + preference?: any +): preference is Array { + return Array.isArray(preference) && preference.every((item) => isAmountPreference(item)); +}; diff --git a/src/model/PaymentRequest.ts b/src/model/PaymentRequest.ts new file mode 100644 index 000000000..edfa6cf03 --- /dev/null +++ b/src/model/PaymentRequest.ts @@ -0,0 +1,76 @@ +import { encodeBase64toUint8 } from '../base64'; +import { decodeCBOR, encodeCBOR } from '../cbor'; +import { + RawPaymentRequest, + RawTransport, + PaymentRequestTransport, + PaymentRequestTransportType +} from './types'; +import { Buffer } from 'buffer'; + +export class PaymentRequest { + constructor( + public transport: Array, + public id?: string, + public amount?: number, + public unit?: string, + public mints?: Array, + public description?: string, + public singleUse: boolean = false + ) {} + + toEncodedRequest() { + const rawRequest: RawPaymentRequest = { + t: this.transport.map((t: PaymentRequestTransport) => ({ t: t.type, a: t.target, g: t.tags })) + }; + if (this.id) { + rawRequest.i = this.id; + } + if (this.amount) { + rawRequest.a = this.amount; + } + if (this.unit) { + rawRequest.u = this.unit; + } + if (this.mints) { + rawRequest.m = this.mints; + } + if (this.description) { + rawRequest.d = this.description; + } + if (this.singleUse) { + rawRequest.s = this.singleUse; + } + + const data = encodeCBOR(rawRequest); + const encodedData = Buffer.from(data).toString('base64'); + return 'creq' + 'A' + encodedData; + } + + getTransport(type: PaymentRequestTransportType) { + return this.transport.find((t: PaymentRequestTransport) => t.type === type); + } + + static fromEncodedRequest(encodedRequest: string): PaymentRequest { + if (!encodedRequest.startsWith('creq')) { + throw new Error('unsupported pr: invalid prefix'); + } + const version = encodedRequest[4]; + if (version !== 'A') { + throw new Error('unsupported pr version'); + } + const encodedData = encodedRequest.slice(5); + const data = encodeBase64toUint8(encodedData); + const decoded = decodeCBOR(data) as RawPaymentRequest; + const transports = decoded.t.map((t: RawTransport) => ({ type: t.t, target: t.a, tags: t.g })); + return new PaymentRequest( + transports, + decoded.i, + decoded.a, + decoded.u, + decoded.m, + decoded.d, + decoded.s + ); + } +} diff --git a/src/model/types/index.ts b/src/model/types/index.ts index d0032a879..5fc2e3b70 100644 --- a/src/model/types/index.ts +++ b/src/model/types/index.ts @@ -1,6 +1,13 @@ +import { AmountPreference } from './wallet/index'; + export * from './mint/index'; export * from './wallet/index'; +export type Preferences = { + sendPreference: Array; + keepPreference?: Array; +}; + export type InvoiceData = { paymentRequest: string; amountInSats?: number; diff --git a/src/model/types/wallet/index.ts b/src/model/types/wallet/index.ts index 93c085fca..3efc7d399 100644 --- a/src/model/types/wallet/index.ts +++ b/src/model/types/wallet/index.ts @@ -1,6 +1,7 @@ export * from './payloads'; export * from './responses'; export * from './tokens'; +export * from './paymentRequests'; export type AmountPreference = { amount: number; diff --git a/src/model/types/wallet/payloads.ts b/src/model/types/wallet/payloads.ts index 43539a91f..7e8b67662 100644 --- a/src/model/types/wallet/payloads.ts +++ b/src/model/types/wallet/payloads.ts @@ -98,6 +98,10 @@ export type MintQuotePayload = { * Amount to be minted */ amount: number; + /** + * Description for the invoice + */ + description?: string; }; /** diff --git a/src/model/types/wallet/paymentRequests.ts b/src/model/types/wallet/paymentRequests.ts new file mode 100644 index 000000000..ef3cc971f --- /dev/null +++ b/src/model/types/wallet/paymentRequests.ts @@ -0,0 +1,36 @@ +import { Proof } from './index'; + +export type RawTransport = { + t: PaymentRequestTransportType; // type + a: string; // target + g?: Array>; // tags +}; + +export type RawPaymentRequest = { + i?: string; // id + a?: number; // amount + u?: string; // unit + s?: boolean; // single use + m?: Array; // mints + d?: string; // description + t: Array; // transports +}; + +export type PaymentRequestTransport = { + type: PaymentRequestTransportType; + target: string; + tags?: Array>; +}; + +export enum PaymentRequestTransportType { + POST = 'post', + NOSTR = 'nostr' +} + +export type PaymentRequestPayload = { + id?: string; + memo?: string; + unit: string; + mint: string; + proofs: Array; +}; diff --git a/src/utils.ts b/src/utils.ts index 00d6ec012..a361eb695 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,16 +2,16 @@ import { encodeBase64ToJson, encodeBase64toUint8, encodeJsonToBase64, - encodeUint8toBase64, encodeUint8toBase64Url } from './base64.js'; import { AmountPreference, Keys, Proof, + RawPaymentRequest, + RawTransport, Token, TokenEntry, - TokenV2, TokenV4Template, V4InnerToken, V4ProofTemplate @@ -20,38 +20,54 @@ import { TOKEN_PREFIX, TOKEN_VERSION } from './utils/Constants.js'; import { bytesToHex, hexToBytes } from '@noble/curves/abstract/utils'; import { sha256 } from '@noble/hashes/sha256'; import { decodeCBOR, encodeCBOR } from './cbor.js'; +import { PaymentRequest } from './model/PaymentRequest.js'; -function splitAmount(value: number, amountPreference?: Array): Array { +function splitAmount( + value: number, + keyset: Keys, + amountPreference?: Array, + isDesc?: boolean +): Array { const chunks: Array = []; if (amountPreference) { - chunks.push(...getPreference(value, amountPreference)); + chunks.push(...getPreference(value, keyset, amountPreference)); value = value - - chunks.reduce((curr, acc) => { + chunks.reduce((curr: number, acc: number) => { return curr + acc; }, 0); } - for (let i = 0; i < 32; i++) { - const mask: number = 1 << i; - if ((value & mask) !== 0) { - chunks.push(Math.pow(2, i)); - } - } - return chunks; + const sortedKeyAmounts: Array = Object.keys(keyset) + .map((k) => parseInt(k)) + .sort((a, b) => b - a); + sortedKeyAmounts.forEach((amt) => { + const q = Math.floor(value / amt); + for (let i = 0; i < q; ++i) chunks.push(amt); + value %= amt; + }); + return chunks.sort((a, b) => (isDesc ? b - a : a - b)); } +/* function isPowerOfTwo(number: number) { return number && !(number & (number - 1)); } +*/ -function getPreference(amount: number, preferredAmounts: Array): Array { +function hasCorrespondingKey(amount: number, keyset: Keys): boolean { + return amount in keyset; +} + +function getPreference( + amount: number, + keyset: Keys, + preferredAmounts: Array +): Array { const chunks: Array = []; let accumulator = 0; - preferredAmounts.forEach((pa) => { - if (!isPowerOfTwo(pa.amount)) { - throw new Error( - 'Provided amount preferences contain non-power-of-2 numbers. Use only ^2 numbers' - ); + preferredAmounts.forEach((pa: AmountPreference) => { + if (!hasCorrespondingKey(pa.amount, keyset)) { + throw new Error('Provided amount preferences do not match the amounts of the mint keyset.'); } for (let i = 1; i <= pa.count; i++) { accumulator += pa.amount; @@ -64,9 +80,9 @@ function getPreference(amount: number, preferredAmounts: Array return chunks; } -function getDefaultAmountPreference(amount: number): Array { - const amounts = splitAmount(amount); - return amounts.map((a) => { +function getDefaultAmountPreference(amount: number, keyset: Keys): Array { + const amounts = splitAmount(amount, keyset); + return amounts.map((a: number) => { return { amount: a, count: 1 }; }); } @@ -117,9 +133,11 @@ function getEncodedTokenV4(token: Token): string { m: mint, u: token.unit || 'sat', t: Object.keys(idMap).map( - (id): V4InnerToken => ({ + (id: string): V4InnerToken => ({ i: hexToBytes(id), - p: idMap[id].map((p): V4ProofTemplate => ({ a: p.amount, s: p.secret, c: hexToBytes(p.C) })) + p: idMap[id].map( + (p: Proof): V4ProofTemplate => ({ a: p.amount, s: p.secret, c: hexToBytes(p.C) }) + ) }) ) } as TokenV4Template; @@ -143,7 +161,7 @@ function getEncodedTokenV4(token: Token): string { function getDecodedToken(token: string) { // remove prefixes const uriPrefixes = ['web+cashu://', 'cashu://', 'cashu:', 'cashu']; - uriPrefixes.forEach((prefix) => { + uriPrefixes.forEach((prefix: string) => { if (!token.startsWith(prefix)) { return; } @@ -170,8 +188,8 @@ function handleTokens(token: string): Token { u: string; }; const mergedTokenEntry: TokenEntry = { mint: tokenData.m, proofs: [] }; - tokenData.t.forEach((tokenEntry) => - tokenEntry.p.forEach((p) => { + tokenData.t.forEach((tokenEntry: V4InnerToken) => + tokenEntry.p.forEach((p: V4ProofTemplate) => { mergedTokenEntry.proofs.push({ secret: p.s, C: bytesToHex(p.c), @@ -191,9 +209,9 @@ function handleTokens(token: string): Token { */ export function deriveKeysetId(keys: Keys) { const pubkeysConcat = Object.entries(keys) - .sort((a, b) => +a[0] - +b[0]) - .map(([, pubKey]) => hexToBytes(pubKey)) - .reduce((prev, curr) => mergeUInt8Arrays(prev, curr), new Uint8Array()); + .sort((a: [string, string], b: [string, string]) => +a[0] - +b[0]) + .map(([, pubKey]: [unknown, string]) => hexToBytes(pubKey)) + .reduce((prev: Uint8Array, curr: Uint8Array) => mergeUInt8Arrays(prev, curr), new Uint8Array()); const hash = sha256(pubkeysConcat); const hashHex = Buffer.from(hash).toString('hex').slice(0, 14); return '00' + hashHex; @@ -208,7 +226,7 @@ function mergeUInt8Arrays(a1: Uint8Array, a2: Uint8Array): Uint8Array { } export function sortProofsById(proofs: Array) { - return proofs.sort((a, b) => a.id.localeCompare(b.id)); + return proofs.sort((a: Proof, b: Proof) => a.id.localeCompare(b.id)); } export function isObj(v: unknown): v is object { @@ -226,13 +244,17 @@ export function checkResponse(data: { error?: string; detail?: string }) { } export function joinUrls(...parts: Array): string { - return parts.map((part) => part.replace(/(^\/+|\/+$)/g, '')).join('/'); + return parts.map((part: string) => part.replace(/(^\/+|\/+$)/g, '')).join('/'); } export function sanitizeUrl(url: string): string { return url.replace(/\/$/, ''); } +function decodePaymentRequest(paymentRequest: string) { + return PaymentRequest.fromEncodedRequest(paymentRequest); +} + export { bigIntStringify, bytesToNumber, @@ -241,5 +263,6 @@ export { getEncodedTokenV4, hexToNumber, splitAmount, - getDefaultAmountPreference + getDefaultAmountPreference, + decodePaymentRequest }; diff --git a/test/integration.test.ts b/test/integration.test.ts index 2d069392d..538c0680c 100644 --- a/test/integration.test.ts +++ b/test/integration.test.ts @@ -61,6 +61,13 @@ describe('mint api', () => { // because local invoice, fee should be 0 expect(fee).toBe(0); }); + test('invoice with description', async () => { + const mint = new CashuMint(mintUrl); + const wallet = new CashuWallet(mint, { unit }); + const quote = await wallet.createMintQuote(100, 'test description'); + expect(quote).toBeDefined(); + console.log(`invoice with description: ${quote.request}`); + }); test('get fee for external invoice', async () => { const mint = new CashuMint(mintUrl); const wallet = new CashuWallet(mint, { unit }); @@ -213,4 +220,27 @@ describe('mint api', () => { }, 0) ).toBe(64); }); + + test('mint and melt p2pk', async () => { + const mint = new CashuMint(mintUrl); + const wallet = new CashuWallet(mint); + + const privKeyBob = secp256k1.utils.randomPrivateKey(); + const pubKeyBob = secp256k1.getPublicKey(privKeyBob); + + const mintRequest = await wallet.createMintQuote(3000); + + const proofs = await wallet.mintTokens(3000, mintRequest.quote, { + pubkey: bytesToHex(pubKeyBob) + }); + + const meltRequest = await wallet.createMeltQuote(externalInvoice); + const fee = meltRequest.fee_reserve; + expect(fee).toBeGreaterThan(0); + const response = await wallet.meltTokens(meltRequest, proofs.proofs, { + privkey: bytesToHex(privKeyBob) + }); + expect(response).toBeDefined(); + expect(response.isPaid).toBe(true); + }); }); diff --git a/test/paymentRequests.test.ts b/test/paymentRequests.test.ts new file mode 100644 index 000000000..b06689dcf --- /dev/null +++ b/test/paymentRequests.test.ts @@ -0,0 +1,65 @@ +import nock from 'nock'; +import { CashuMint } from '../src/CashuMint.js'; +import { CashuWallet } from '../src/CashuWallet.js'; +import { setGlobalRequestOptions } from '../src/request.js'; +import { MeltQuoteResponse } from '../src/model/types/index.js'; +import { + decodePaymentRequest, + PaymentRequest, + PaymentRequestPayload, + PaymentRequestTransport, + PaymentRequestTransportType +} from '../src/index.js'; + +describe('payment requests', () => { + test('encode payment requests', async () => { + const request = new PaymentRequest( + [ + { + type: PaymentRequestTransportType.NOSTR, + target: 'asd', + tags: [['n', '17']] + } as PaymentRequestTransport + ], + '4840f51e', + 1000, + 'sat', + ['https://mint.com'], + 'test', + true // single use + ); + const pr = request.toEncodedRequest(); + expect(pr).toBeDefined(); + const decodedRequest = decodePaymentRequest(pr); + expect(decodedRequest).toBeDefined(); + expect(decodedRequest.id).toBe('4840f51e'); + expect(decodedRequest.amount).toBe(1000); + expect(decodedRequest.unit).toBe('sat'); + expect(decodedRequest.mints).toStrictEqual(['https://mint.com']); + expect(decodedRequest.description).toBe('test'); + expect(decodedRequest.transport).toHaveLength(1); + expect(decodedRequest.singleUse).toBe(true); + expect(decodedRequest.transport[0].type).toBe(PaymentRequestTransportType.NOSTR); + expect(decodedRequest.transport[0].target).toBe('asd'); + expect(decodedRequest.transport[0].tags).toStrictEqual([['n', '17']]); + + const decodedRequestClassConstructor = PaymentRequest.fromEncodedRequest(pr); + expect(decodedRequestClassConstructor).toStrictEqual(decodedRequest); + }); + test('test decoding payment requests with no amount', async () => { + const prWithoutAmount = + 'creqApGF0gaNhdGVub3N0cmFheKlucHJvZmlsZTFxeTI4d3VtbjhnaGo3dW45ZDNzaGp0bnl2OWtoMnVld2Q5aHN6OW1od2RlbjV0ZTB3ZmprY2N0ZTljdXJ4dmVuOWVlaHFjdHJ2NWhzenJ0aHdkZW41dGUwZGVoaHh0bnZkYWtxcWd5bWRleDNndmZzZnVqcDN4eW43ZTdxcnM4eXlxOWQ4enN1MnpxdWp4dXhjYXBmcXZ6YzhncnFka3RzYWeBgmFuYjE3YWloNDg0MGY1MWVhdWNzYXRhbYFwaHR0cHM6Ly9taW50LmNvbQ=='; + const request: PaymentRequest = decodePaymentRequest(prWithoutAmount); + expect(request).toBeDefined(); + expect(request.id).toBe('4840f51e'); + expect(request.amount).toBeUndefined(); + expect(request.unit).toBe('sat'); + expect(request.mints).toStrictEqual(['https://mint.com']); + expect(request.description).toBeUndefined(); + expect(request.transport).toHaveLength(1); + expect(request.transport[0].type).toBe(PaymentRequestTransportType.NOSTR); + expect(request.transport[0].target).toBe( + 'nprofile1qy28wumn8ghj7un9d3shjtnyv9kh2uewd9hsz9mhwden5te0wfjkccte9curxven9eehqctrv5hszrthwden5te0dehhxtnvdakqqgymdex3gvfsfujp3xyn7e7qrs8yyq9d8zsu2zqujxuxcapfqvzc8grqdkts' + ); + }); +}); diff --git a/test/utils.test.ts b/test/utils.test.ts index c686b8992..8422f44d1 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -1,14 +1,29 @@ -import { AmountPreference, Token } from '../src/model/types/index.js'; +import { AmountPreference, Token, Keys } from '../src/model/types/index.js'; import * as utils from '../src/utils.js'; import { PUBKEYS } from './consts.js'; +const keys: Keys = {}; +for (let i = 1; i <= 2048; i *= 2) { + keys[i] = 'deadbeef'; +} + +const keys_base10: Keys = {}; +for (let i = 1; i <= 10000; i *= 10) { + keys_base10[i] = 'deadbeef'; +} + +const keys_base16: Keys = {}; +for (let i = 1; i <= 0x10000; i *= 16) { + keys_base16[i] = 'deadbeef'; +} + describe('test split amounts ', () => { test('testing amount 2561', async () => { - const chunks = utils.splitAmount(2561); + const chunks = utils.splitAmount(2561, keys); expect(chunks).toStrictEqual([1, 512, 2048]); }); test('testing amount 0', async () => { - const chunks = utils.splitAmount(0); + const chunks = utils.splitAmount(0, keys); expect(chunks).toStrictEqual([]); }); }); @@ -16,7 +31,7 @@ describe('test split amounts ', () => { describe('test split custom amounts ', () => { const fiveToOne: AmountPreference = { amount: 1, count: 5 }; test('testing amount 5', async () => { - const chunks = utils.splitAmount(5, [fiveToOne]); + const chunks = utils.splitAmount(5, keys, [fiveToOne]); expect(chunks).toStrictEqual([1, 1, 1, 1, 1]); }); const tenToOneAndTwo: Array = [ @@ -24,25 +39,47 @@ describe('test split custom amounts ', () => { { amount: 2, count: 4 } ]; test('testing amount 10', async () => { - const chunks = utils.splitAmount(10, tenToOneAndTwo); + const chunks = utils.splitAmount(10, keys, tenToOneAndTwo); expect(chunks).toStrictEqual([1, 1, 2, 2, 2, 2]); }); const fiveTwelve: Array = [{ amount: 512, count: 2 }]; - test('testing amount 516', async () => { - const chunks = utils.splitAmount(518, fiveTwelve); - expect(chunks).toStrictEqual([512, 2, 4]); + test('testing amount 518', async () => { + const chunks = utils.splitAmount(518, keys, fiveTwelve, true); + expect(chunks).toStrictEqual([512, 4, 2]); }); const illegal: Array = [{ amount: 3, count: 2 }]; test('testing non pow2', async () => { - expect(() => utils.splitAmount(6, illegal)).toThrowError(); + expect(() => utils.splitAmount(6, keys, illegal)).toThrowError(); }); const empty: Array = []; test('testing empty', async () => { - const chunks = utils.splitAmount(5, empty); + const chunks = utils.splitAmount(5, keys, empty, true); + expect(chunks).toStrictEqual([4, 1]); + }); + const undef = undefined; + test('testing undefined', async () => { + const chunks = utils.splitAmount(5, keys, undef); expect(chunks).toStrictEqual([1, 4]); }); }); +describe('test split different key amount', () => { + test('testing amount 68251', async () => { + const chunks = utils.splitAmount(68251, keys_base10, undefined, true); + expect(chunks).toStrictEqual([ + 10000, 10000, 10000, 10000, 10000, 10000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 100, + 100, 10, 10, 10, 10, 10, 1 + ]); + }); + test('testing amount 1917', async () => { + const chunks = utils.splitAmount(1917, keys_base16); + expect(chunks).toStrictEqual([ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16, 16, 16, 256, 256, 256, 256, 256, + 256, 256 + ]); + }); +}); + describe('test decode token', () => { test('testing v1 Token', () => { const token = diff --git a/test/wallet.test.ts b/test/wallet.test.ts index 913c02c4a..85608d170 100644 --- a/test/wallet.test.ts +++ b/test/wallet.test.ts @@ -491,7 +491,9 @@ describe('send', () => { C: '034268c0bd30b945adf578aca2dc0d1e26ef089869aaf9a08ba3a6da40fda1d8be' } ]; - const result = await wallet.send(4, overpayProofs, { preference: [{ amount: 1, count: 4 }] }); + const result = await wallet.send(4, overpayProofs, { + preference: { sendPreference: [{ amount: 1, count: 4 }] } + }); expect(result.send).toHaveLength(4); expect(result.send[0]).toMatchObject({ amount: 1, id: '009a1f293253e41e' }); @@ -546,7 +548,9 @@ describe('send', () => { C: '034268c0bd30b945adf578aca2dc0d1e26ef089869aaf9a08ba3a6da40fda1d8be' } ]; - const result = await wallet.send(4, overpayProofs, { preference: [{ amount: 1, count: 3 }] }); + const result = await wallet.send(4, overpayProofs, { + preference: { sendPreference: [{ amount: 1, count: 3 }] } + }); expect(result.send).toHaveLength(3); expect(result.send[0]).toMatchObject({ amount: 1, id: '009a1f293253e41e' }); From 438c10a234c14dd8fc37d1363553769b6edc43a6 Mon Sep 17 00:00:00 2001 From: Egge Date: Thu, 24 Oct 2024 10:00:00 +0100 Subject: [PATCH 38/39] pipe: removed nextVersion workflow --- .github/workflows/nextVersion.yml | 24 ------------------------ package.json | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 .github/workflows/nextVersion.yml diff --git a/.github/workflows/nextVersion.yml b/.github/workflows/nextVersion.yml deleted file mode 100644 index 964ce5baa..000000000 --- a/.github/workflows/nextVersion.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Publish Package to npmjs -permissions: - contents: write - id-token: write -on: - push: - branches: - - staging -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 - with: - node-version: 20 - registry-url: 'https://registry.npmjs.org' - - run: npm i - - run: npm run compile - - run: npm version prerelease --preid=rc --no-git-tag-version - - run: git push - - run: npm publish --provenance --access public --tag next - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/package.json b/package.json index 813c3ad00..cbba8c094 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cashu/cashu-ts", - "version": "1.2.0", + "version": "1.2.1-rc.0", "description": "cashu library for communicating with a cashu mint", "main": "dist/lib/es5/index.js", "module": "dist/lib/es6/index.js", From cb90f4368b50107db93b9b20a6d12385ee94cd43 Mon Sep 17 00:00:00 2001 From: Egge Date: Thu, 24 Oct 2024 10:04:02 +0100 Subject: [PATCH 39/39] Prep Release v1.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cbba8c094..c002a1110 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cashu/cashu-ts", - "version": "1.2.1-rc.0", + "version": "1.2.1", "description": "cashu library for communicating with a cashu mint", "main": "dist/lib/es5/index.js", "module": "dist/lib/es6/index.js",