diff --git a/package-lock.json b/package-lock.json index 9ea2d4cdc..2e3f60c25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -101,7 +101,7 @@ "ts-jest": "^29.4.1", "ts-node": "^10.9.2", "typescript": "^5.9.3", - "xrpl": "^4.5.0" + "xrpl": "^5.1.0" }, "engines": { "node": ">=22.0.0 <23", @@ -162,6 +162,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -786,6 +787,7 @@ "integrity": "sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1711,6 +1713,7 @@ "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-module-imports": "^7.28.6", @@ -2240,8 +2243,7 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@cacheable/memory": { "version": "2.0.8", @@ -2279,6 +2281,7 @@ "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@keyv/serialize": "^1.1.1" } @@ -2412,6 +2415,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -2459,6 +2463,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" } @@ -3171,7 +3176,6 @@ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -3190,7 +3194,6 @@ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -3204,7 +3207,6 @@ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^6.2.2" }, @@ -3248,7 +3250,6 @@ "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -3267,7 +3268,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -3281,7 +3281,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -3300,8 +3299,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@jest/console/node_modules/jest-util": { "version": "30.3.0", @@ -3309,7 +3307,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -3328,7 +3325,6 @@ "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/console": "30.3.0", "@jest/pattern": "30.0.1", @@ -3376,7 +3372,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -3390,7 +3385,6 @@ "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.27.4", "@jest/types": "30.3.0", @@ -3417,7 +3411,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -3436,8 +3429,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@jest/core/node_modules/ansi-styles": { "version": "5.2.0", @@ -3445,7 +3437,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -3459,7 +3450,6 @@ "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "workspaces": [ "test/babel-8" ], @@ -3480,7 +3470,6 @@ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -3498,7 +3487,6 @@ "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -3524,7 +3512,6 @@ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } @@ -3535,7 +3522,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -3554,7 +3540,6 @@ "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", @@ -3569,8 +3554,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@jest/core/node_modules/semver": { "version": "7.7.4", @@ -3578,7 +3562,6 @@ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -3592,7 +3575,6 @@ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -3748,7 +3730,6 @@ "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "expect": "30.3.0", "jest-snapshot": "30.3.0" @@ -3856,7 +3837,6 @@ "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/environment": "30.3.0", "@jest/expect": "30.3.0", @@ -3873,7 +3853,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -3887,7 +3866,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -3906,8 +3884,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@jest/pattern": { "version": "30.0.1", @@ -3937,7 +3914,6 @@ "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "30.3.0", @@ -3981,7 +3957,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -3995,7 +3970,6 @@ "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.27.4", "@jest/types": "30.3.0", @@ -4022,7 +3996,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -4041,8 +4014,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@jest/reporters/node_modules/babel-plugin-istanbul": { "version": "7.0.1", @@ -4050,7 +4022,6 @@ "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "workspaces": [ "test/babel-8" ], @@ -4071,7 +4042,6 @@ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -4089,7 +4059,6 @@ "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -4115,7 +4084,6 @@ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } @@ -4126,7 +4094,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -4145,7 +4112,6 @@ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -4159,7 +4125,6 @@ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -4187,7 +4152,6 @@ "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "chalk": "^4.1.2", @@ -4204,7 +4168,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -4218,7 +4181,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -4237,8 +4199,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@jest/source-map": { "version": "30.0.1", @@ -4246,7 +4207,6 @@ "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "callsites": "^3.1.0", @@ -4262,7 +4222,6 @@ "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/console": "30.3.0", "@jest/types": "30.3.0", @@ -4279,7 +4238,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -4293,7 +4251,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -4312,8 +4269,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@jest/test-sequencer": { "version": "30.3.0", @@ -4321,7 +4277,6 @@ "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/test-result": "30.3.0", "graceful-fs": "^4.2.11", @@ -4338,7 +4293,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -4352,7 +4306,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -4371,8 +4324,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@jest/test-sequencer/node_modules/jest-haste-map": { "version": "30.3.0", @@ -4380,7 +4332,6 @@ "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -4406,7 +4357,6 @@ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } @@ -4417,7 +4367,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -4561,29 +4510,28 @@ } }, "node_modules/@noble/curves": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", - "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "version": "2.4.0", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/@noble/curves/-/curves-2.4.0.tgz", + "integrity": "sha512-P4/62zrgfH33CneE3Dn4WhJVA22YUU0eR51wKIan4NVRvwsA0YnPTwWGpNbpuacSujmSFLvyzpyuR30+fbq2Ew==", "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "1.8.0" + "@noble/hashes": "2.4.0" }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "dev": true, + "version": "2.4.0", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/@noble/hashes/-/hashes-2.4.0.tgz", + "integrity": "sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==", "license": "MIT", "engines": { - "node": "^14.21.3 || >=16" + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -4941,7 +4889,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=14" } @@ -5349,39 +5296,37 @@ "license": "MIT" }, "node_modules/@scure/base": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", - "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "dev": true, + "version": "2.4.0", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/@scure/base/-/base-2.4.0.tgz", + "integrity": "sha512-thZ1TuJwFwBblOhgsjDKvvGirBxNp+wSvY/DR6tJBJOTDhdAAcHJ8Vbr2eFnqaxeca4+t0i9KBf+uHYGWwZORg==", "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@scure/bip32": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", - "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "version": "2.4.0", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/@scure/bip32/-/bip32-2.4.0.tgz", + "integrity": "sha512-i3DS0CptAocyvqE4n3SUkpzeQK4vJMFwWLofTwRiiKo2aWojBOfyMCgfKw9HVpO6fSY5AK86sHS/Uzn8kK9Few==", "dev": true, "license": "MIT", "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" + "@noble/curves": "2.4.0", + "@noble/hashes": "2.4.0", + "@scure/base": "2.4.0" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@scure/bip39": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", - "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "version": "2.4.0", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/@scure/bip39/-/bip39-2.4.0.tgz", + "integrity": "sha512-82dxFbZUYboyOf0AXiydsQrFQ5Q4h9mX+O2UkE91ROYmsc0BKMGZLwDmy96Jpa2+vrtoxomjUhy1RPIgH/r2nA==", "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" + "@noble/hashes": "2.4.0" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -6120,6 +6065,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz", "integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==", "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -6144,6 +6090,7 @@ "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -6410,6 +6357,7 @@ "integrity": "sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.58.2", "@typescript-eslint/types": "8.58.2", @@ -6931,16 +6879,14 @@ "node": ">=18.0.0" } }, - "node_modules/@xrplf/isomorphic/node_modules/@noble/hashes": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.3.0.tgz", - "integrity": "sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==", - "license": "MIT", + "node_modules/@xrplf/mpt-crypto": { + "version": "0.1.1", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/@xrplf/mpt-crypto/-/mpt-crypto-0.1.1.tgz", + "integrity": "sha512-Wv9wbk60DRGWvI+B9DITwfWygCWDfEjv8yWxiLJyDf/G8UPkfhVlUKIflF9nMaBFMygPRkXrpO1jNqTj6/vJow==", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">= 18" } }, "node_modules/@xrplf/prettier-config": { @@ -6951,14 +6897,14 @@ "license": "ISC" }, "node_modules/@xrplf/secret-numbers": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@xrplf/secret-numbers/-/secret-numbers-2.0.0.tgz", - "integrity": "sha512-z3AOibRTE9E8MbjgzxqMpG1RNaBhQ1jnfhNCa1cGf2reZUJzPMYs4TggQTc7j8+0WyV3cr7y/U8Oz99SXIkN5Q==", + "version": "3.0.0", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/@xrplf/secret-numbers/-/secret-numbers-3.0.0.tgz", + "integrity": "sha512-qpGhAZXv5noMDjCtfzq5NK0y5rrdwTVjKhhPcAYSE+a/gogBOgqdpCKyieprVVPCnmVmJnGeRoZKBAqpCGegsA==", "dev": true, "license": "ISC", "dependencies": { - "@xrplf/isomorphic": "^1.0.1", - "ripple-keypairs": "^2.0.0" + "@xrplf/isomorphic": "^1.0.2", + "ripple-keypairs": "^3.0.0" } }, "node_modules/accepts": { @@ -6988,6 +6934,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -7050,7 +6997,6 @@ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "type-fest": "^0.21.3" }, @@ -7067,7 +7013,6 @@ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "license": "(MIT OR CC0-1.0)", - "peer": true, "engines": { "node": ">=10" }, @@ -7496,6 +7441,7 @@ "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", @@ -7752,14 +7698,10 @@ } }, "node_modules/bignumber.js": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", - "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } + "version": "10.0.2", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/bignumber.js/-/bignumber.js-10.0.2.tgz", + "integrity": "sha512-E8Wp9O06QA6lneJ4aRUXKYf/1GIomqUEmUMwtIOMtDxf1U52ffJY+y7JBk/8wRafA8qOIqLnXQGqonYXZdBnFQ==", + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", @@ -7879,6 +7821,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", @@ -8141,7 +8084,6 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" } @@ -8204,8 +8146,7 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/classnames": { "version": "2.5.1", @@ -8327,7 +8268,6 @@ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -8342,8 +8282,7 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cliui/node_modules/is-fullwidth-code-point": { "version": "3.0.0", @@ -8351,7 +8290,6 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -8362,7 +8300,6 @@ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -8378,7 +8315,6 @@ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8406,7 +8342,6 @@ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -8417,8 +8352,7 @@ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", @@ -8700,6 +8634,7 @@ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "mdn-data": "2.27.1", "source-map-js": "^1.2.1" @@ -9107,6 +9042,7 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -9300,7 +9236,6 @@ "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "dev": true, "license": "MIT", - "peer": true, "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, @@ -9356,7 +9291,6 @@ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -9459,7 +9393,6 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -9668,8 +9601,7 @@ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", @@ -9704,7 +9636,6 @@ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -10082,6 +10013,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -10180,6 +10112,7 @@ "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -10222,6 +10155,7 @@ "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", @@ -10257,6 +10191,7 @@ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -10653,6 +10588,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -10741,6 +10677,7 @@ "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "aria-query": "^5.3.2", "array-includes": "^3.1.8", @@ -10843,6 +10780,7 @@ "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", @@ -10876,6 +10814,7 @@ "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -11456,7 +11395,6 @@ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -11480,8 +11418,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/exit-x": { "version": "0.2.2", @@ -11489,7 +11426,6 @@ "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8.0" } @@ -11938,7 +11874,6 @@ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" @@ -12165,7 +12100,6 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -12211,7 +12145,6 @@ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -12245,8 +12178,7 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/glob/node_modules/brace-expansion": { "version": "2.1.0", @@ -12254,7 +12186,6 @@ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -12265,7 +12196,6 @@ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^2.0.2" }, @@ -12625,8 +12555,7 @@ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/html-minifier-terser": { "version": "6.1.0", @@ -12732,7 +12661,6 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=10.17.0" } @@ -12756,6 +12684,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.23.2" } @@ -12865,7 +12794,6 @@ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -13229,7 +13157,6 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -13412,7 +13339,6 @@ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" }, @@ -13582,7 +13508,6 @@ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -13598,7 +13523,6 @@ "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", @@ -13614,7 +13538,6 @@ "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -13647,7 +13570,6 @@ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "license": "BlueOak-1.0.0", - "peer": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -13681,7 +13603,6 @@ "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "30.3.0", "@jest/types": "30.3.0", @@ -13709,7 +13630,6 @@ "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "execa": "^5.1.1", "jest-util": "30.3.0", @@ -13725,7 +13645,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -13739,7 +13658,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -13758,8 +13676,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-changed-files/node_modules/jest-util": { "version": "30.3.0", @@ -13767,7 +13684,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -13786,7 +13702,6 @@ "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/environment": "30.3.0", "@jest/expect": "30.3.0", @@ -13819,7 +13734,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -13833,7 +13747,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -13852,8 +13765,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-circus/node_modules/ansi-styles": { "version": "5.2.0", @@ -13861,7 +13773,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -13875,7 +13786,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -13894,7 +13804,6 @@ "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", @@ -13909,8 +13818,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-cli": { "version": "30.3.0", @@ -13918,7 +13826,6 @@ "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "30.3.0", "@jest/test-result": "30.3.0", @@ -13952,7 +13859,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -13966,7 +13872,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -13985,8 +13890,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-cli/node_modules/jest-util": { "version": "30.3.0", @@ -13994,7 +13898,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -14013,7 +13916,6 @@ "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.27.4", "@jest/get-type": "30.1.0", @@ -14065,7 +13967,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -14079,7 +13980,6 @@ "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.27.4", "@jest/types": "30.3.0", @@ -14106,7 +14006,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -14125,8 +14024,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-config/node_modules/ansi-styles": { "version": "5.2.0", @@ -14134,7 +14032,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -14148,7 +14045,6 @@ "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/transform": "30.3.0", "@types/babel__core": "^7.20.5", @@ -14171,7 +14067,6 @@ "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "workspaces": [ "test/babel-8" ], @@ -14192,7 +14087,6 @@ "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/babel__core": "^7.20.5" }, @@ -14206,7 +14100,6 @@ "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "babel-plugin-jest-hoist": "30.3.0", "babel-preset-current-node-syntax": "^1.2.0" @@ -14224,7 +14117,6 @@ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -14242,7 +14134,6 @@ "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -14268,7 +14159,6 @@ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } @@ -14279,7 +14169,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -14298,7 +14187,6 @@ "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", @@ -14313,8 +14201,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-config/node_modules/semver": { "version": "7.7.4", @@ -14322,7 +14209,6 @@ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -14336,7 +14222,6 @@ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -14422,7 +14307,6 @@ "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "detect-newline": "^3.1.0" }, @@ -14436,7 +14320,6 @@ "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/get-type": "30.1.0", "@jest/types": "30.3.0", @@ -14454,7 +14337,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -14468,7 +14350,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -14487,8 +14368,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-each/node_modules/ansi-styles": { "version": "5.2.0", @@ -14496,7 +14376,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -14510,7 +14389,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -14529,7 +14407,6 @@ "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", @@ -14544,8 +14421,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-environment-jsdom": { "version": "30.3.0", @@ -14575,7 +14451,6 @@ "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/environment": "30.3.0", "@jest/fake-timers": "30.3.0", @@ -14595,7 +14470,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -14609,7 +14483,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -14628,8 +14501,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-environment-node/node_modules/jest-util": { "version": "30.3.0", @@ -14637,7 +14509,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -14724,7 +14595,6 @@ "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/get-type": "30.1.0", "pretty-format": "30.3.0" @@ -14739,7 +14609,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -14752,8 +14621,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-leak-detector/node_modules/ansi-styles": { "version": "5.2.0", @@ -14761,7 +14629,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -14775,7 +14642,6 @@ "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", @@ -14790,8 +14656,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-matcher-utils": { "version": "30.3.0", @@ -15025,7 +14890,6 @@ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" }, @@ -15054,7 +14918,6 @@ "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", @@ -15075,7 +14938,6 @@ "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "jest-regex-util": "30.0.1", "jest-snapshot": "30.3.0" @@ -15090,7 +14952,6 @@ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } @@ -15101,7 +14962,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -15115,7 +14975,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -15134,8 +14993,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-resolve/node_modules/jest-haste-map": { "version": "30.3.0", @@ -15143,7 +15001,6 @@ "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -15169,7 +15026,6 @@ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } @@ -15180,7 +15036,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -15199,7 +15054,6 @@ "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/console": "30.3.0", "@jest/environment": "30.3.0", @@ -15234,7 +15088,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -15248,7 +15101,6 @@ "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.27.4", "@jest/types": "30.3.0", @@ -15275,7 +15127,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -15294,8 +15145,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-runner/node_modules/babel-plugin-istanbul": { "version": "7.0.1", @@ -15303,7 +15153,6 @@ "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "workspaces": [ "test/babel-8" ], @@ -15324,7 +15173,6 @@ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -15342,7 +15190,6 @@ "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -15368,7 +15215,6 @@ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } @@ -15379,7 +15225,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -15398,7 +15243,6 @@ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -15412,7 +15256,6 @@ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -15427,7 +15270,6 @@ "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/environment": "30.3.0", "@jest/fake-timers": "30.3.0", @@ -15462,7 +15304,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -15476,7 +15317,6 @@ "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.27.4", "@jest/types": "30.3.0", @@ -15503,7 +15343,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -15522,8 +15361,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-runtime/node_modules/babel-plugin-istanbul": { "version": "7.0.1", @@ -15531,7 +15369,6 @@ "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "workspaces": [ "test/babel-8" ], @@ -15552,7 +15389,6 @@ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -15570,7 +15406,6 @@ "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -15596,7 +15431,6 @@ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } @@ -15607,7 +15441,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -15626,7 +15459,6 @@ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -15640,7 +15472,6 @@ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -15655,7 +15486,6 @@ "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.27.4", "@babel/generator": "^7.27.5", @@ -15689,7 +15519,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -15703,7 +15532,6 @@ "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.27.4", "@jest/types": "30.3.0", @@ -15730,7 +15558,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -15749,8 +15576,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-snapshot/node_modules/ansi-styles": { "version": "5.2.0", @@ -15758,7 +15584,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -15772,7 +15597,6 @@ "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "workspaces": [ "test/babel-8" ], @@ -15793,7 +15617,6 @@ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -15811,7 +15634,6 @@ "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -15837,7 +15659,6 @@ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } @@ -15848,7 +15669,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -15867,7 +15687,6 @@ "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", @@ -15882,8 +15701,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-snapshot/node_modules/semver": { "version": "7.7.4", @@ -15891,7 +15709,6 @@ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -15905,7 +15722,6 @@ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -15967,7 +15783,6 @@ "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/get-type": "30.1.0", "@jest/types": "30.3.0", @@ -15986,7 +15801,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -16000,7 +15814,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -16019,8 +15832,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-validate/node_modules/ansi-styles": { "version": "5.2.0", @@ -16028,7 +15840,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -16042,7 +15853,6 @@ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -16056,7 +15866,6 @@ "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", @@ -16071,8 +15880,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-watcher": { "version": "30.3.0", @@ -16080,7 +15888,6 @@ "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/test-result": "30.3.0", "@jest/types": "30.3.0", @@ -16101,7 +15908,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -16115,7 +15921,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -16134,8 +15939,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-watcher/node_modules/jest-util": { "version": "30.3.0", @@ -16143,7 +15947,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -16224,7 +16027,6 @@ "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/node": "*", "@ungap/structured-clone": "^1.3.0", @@ -16242,7 +16044,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -16256,7 +16057,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -16275,8 +16075,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-worker/node_modules/jest-util": { "version": "30.3.0", @@ -16284,7 +16083,6 @@ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", @@ -16303,7 +16101,6 @@ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -16320,7 +16117,6 @@ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sinclair/typebox": "^0.34.0" }, @@ -16334,7 +16130,6 @@ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", @@ -16353,8 +16148,7 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/js-sha3": { "version": "0.8.0", @@ -16387,6 +16181,7 @@ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "license": "MIT", + "peer": true, "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", @@ -16560,7 +16355,6 @@ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -17178,7 +16972,6 @@ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "semver": "^7.5.3" }, @@ -17195,7 +16988,6 @@ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -17401,7 +17193,6 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -17461,7 +17252,6 @@ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, "license": "BlueOak-1.0.0", - "peer": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -18134,7 +17924,6 @@ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "path-key": "^3.0.0" }, @@ -18337,7 +18126,6 @@ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -18461,8 +18249,7 @@ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true, - "license": "BlueOak-1.0.0", - "peer": true + "license": "BlueOak-1.0.0" }, "node_modules/param-case": { "version": "3.0.4", @@ -18577,7 +18364,6 @@ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, "license": "BlueOak-1.0.0", - "peer": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -18594,8 +18380,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/path-to-regexp": { "version": "0.1.13", @@ -18675,7 +18460,6 @@ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "find-up": "^4.0.0" }, @@ -18711,6 +18495,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -18794,6 +18579,7 @@ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -18834,6 +18620,7 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -18955,8 +18742,7 @@ "url": "https://opencollective.com/fast-check" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/qified": { "version": "0.9.1", @@ -19042,6 +18828,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -19054,6 +18841,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -19520,7 +19308,6 @@ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "resolve-from": "^5.0.0" }, @@ -19676,19 +19463,10 @@ "node": ">= 18" } }, - "node_modules/ripple-address-codec/node_modules/@scure/base": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-2.3.0.tgz", - "integrity": "sha512-NsG6Y03tY6R5BUis4FdVtHVkur0U6FOzskgs9ZXNl78CUc9fkZ78HmENUle1nSOkCasDmbubmWD9qwB7mm4PZA==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/ripple-binary-codec": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-2.9.0.tgz", - "integrity": "sha512-DOv4CPwm2B5mjAJNHE4tfes7tIqefi85iun8BskS7/i1PvLIwVydHIbTV5hbQ7eT69Zg4K5dtO1CzfuvQVAYvQ==", + "version": "2.10.0", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/ripple-binary-codec/-/ripple-binary-codec-2.10.0.tgz", + "integrity": "sha512-H4pBm2WdOMmVnA0HGUdWAShmUFdmqavWAsi2WlMCzOknc1XjrZssa/RxEyziaPww8MXe1OpgGU7uCs8G2nYe/A==", "license": "ISC", "dependencies": { "@xrplf/isomorphic": "^1.0.2", @@ -19699,25 +19477,19 @@ "node": ">= 18" } }, - "node_modules/ripple-binary-codec/node_modules/bignumber.js": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-10.0.2.tgz", - "integrity": "sha512-E8Wp9O06QA6lneJ4aRUXKYf/1GIomqUEmUMwtIOMtDxf1U52ffJY+y7JBk/8wRafA8qOIqLnXQGqonYXZdBnFQ==", - "license": "MIT" - }, "node_modules/ripple-keypairs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-2.0.0.tgz", - "integrity": "sha512-b5rfL2EZiffmklqZk1W+dvSy97v3V/C7936WxCCgDynaGPp7GE6R2XO7EU9O2LlM/z95rj870IylYnOQs+1Rag==", + "version": "3.0.0", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/ripple-keypairs/-/ripple-keypairs-3.0.0.tgz", + "integrity": "sha512-lE69pD0E8hFNCqZoVXRyY45Yi8Ku+Qw7Rf1qRwPj4nOi34vp9NAuwzfiJH1IwXGWNCfEkwVfctG99CPTEoUf+g==", "dev": true, "license": "ISC", "dependencies": { - "@noble/curves": "^1.0.0", - "@xrplf/isomorphic": "^1.0.0", - "ripple-address-codec": "^5.0.0" + "@noble/curves": "^2.0.1", + "@xrplf/isomorphic": "^1.0.2", + "ripple-address-codec": "^5.0.1" }, "engines": { - "node": ">= 16" + "node": ">= 18" } }, "node_modules/robust-predicates": { @@ -19731,6 +19503,7 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -19898,6 +19671,7 @@ "integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.1.5", @@ -20493,7 +20267,6 @@ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -20505,7 +20278,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -20623,7 +20395,6 @@ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -20645,7 +20416,6 @@ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -20665,7 +20435,6 @@ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -20680,8 +20449,7 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", @@ -20689,7 +20457,6 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -20700,7 +20467,6 @@ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -20714,7 +20480,6 @@ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^6.2.2" }, @@ -20877,7 +20642,6 @@ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -20891,7 +20655,6 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -20902,7 +20665,6 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -20949,6 +20711,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", @@ -21180,6 +20943,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=20.19.0" }, @@ -21203,6 +20967,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=20.19.0" } @@ -21977,6 +21742,7 @@ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -22247,6 +22013,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -22393,6 +22160,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "napi-postinstall": "^0.3.0" }, @@ -22531,7 +22299,6 @@ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -22588,6 +22355,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -23462,7 +23230,6 @@ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -23482,7 +23249,6 @@ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -23500,8 +23266,7 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", @@ -23509,7 +23274,6 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -23520,7 +23284,6 @@ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -23536,7 +23299,6 @@ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -23550,7 +23312,6 @@ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -23564,7 +23325,6 @@ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^6.2.2" }, @@ -23639,25 +23399,26 @@ "license": "MIT" }, "node_modules/xrpl": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/xrpl/-/xrpl-4.6.0.tgz", - "integrity": "sha512-0nXZfqDHRJ6bsDv1WtA9MdCYalMtXuxVa9mtLdqT3xypRKf2LwT5DbuGL/kHcVfuqk3B+ly+SFARlrnX+LHtRQ==", + "version": "5.1.0", + "resolved": "https://artifactory.ops.ripple.com/artifactory/api/npm/ripple-npm/xrpl/-/xrpl-5.1.0.tgz", + "integrity": "sha512-wYTiyrFqV22kwSX2lrUCD10Ns8Zyv2zz8rZ2Pi0KOVm5Sc7/8m7rrca2dAZy1vGhOt36tkvWyX4aC2SQveyT9w==", "dev": true, "license": "ISC", "dependencies": { - "@scure/bip32": "^1.3.1", - "@scure/bip39": "^1.2.1", - "@xrplf/isomorphic": "^1.0.1", - "@xrplf/secret-numbers": "^2.0.0", - "bignumber.js": "^9.0.0", + "@scure/bip32": "^2.0.1", + "@scure/bip39": "^2.0.1", + "@xrplf/isomorphic": "^1.0.2", + "@xrplf/mpt-crypto": "^0.1.1", + "@xrplf/secret-numbers": "^3.0.0", + "bignumber.js": "^10.0.2", "eventemitter3": "^5.0.1", "fast-json-stable-stringify": "^2.1.0", - "ripple-address-codec": "^5.0.0", - "ripple-binary-codec": "^2.7.0", - "ripple-keypairs": "^2.0.0" + "ripple-address-codec": "^5.0.1", + "ripple-binary-codec": "^2.10.0", + "ripple-keypairs": "^3.0.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.19.0" } }, "node_modules/xrpl-client": { @@ -23702,6 +23463,7 @@ "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "devOptional": true, "license": "ISC", + "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -23718,7 +23480,6 @@ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -23747,8 +23508,7 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", @@ -23756,7 +23516,6 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -23767,7 +23526,6 @@ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", diff --git a/package.json b/package.json index cc8d56238..3c11e9c5e 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "ts-jest": "^29.4.1", "ts-node": "^10.9.2", "typescript": "^5.9.3", - "xrpl": "^4.5.0" + "xrpl": "^5.1.0" }, "resolutions": { "jest-environment-jsdom": "29.3.1", diff --git a/public/locales/ca-CA/translations.json b/public/locales/ca-CA/translations.json index bc4553c11..59207d471 100644 --- a/public/locales/ca-CA/translations.json +++ b/public/locales/ca-CA/translations.json @@ -208,6 +208,8 @@ "transaction_type_name_SetHook": "Establir Hook", "transaction_type_name_SetRegularKey": "Establir Clau Regular", "transaction_type_name_SignerListSet": "Etablir Llista de Signantst", + "transaction_type_name_SponsorshipSet": null, + "transaction_type_name_SponsorshipTransfer": null, "transaction_type_name_TicketCreate": "Crear tiquet", "transaction_type_name_TrustSet": "Establir Confiança", "transaction_type_name_VaultCreate": null, diff --git a/public/locales/en-US/translations.json b/public/locales/en-US/translations.json index 8c55a6a7f..15afc600d 100644 --- a/public/locales/en-US/translations.json +++ b/public/locales/en-US/translations.json @@ -209,6 +209,8 @@ "transaction_type_name_SetHook": "Set Hook", "transaction_type_name_SetRegularKey": "Set Regular Key", "transaction_type_name_SignerListSet": "Signer List Set", + "transaction_type_name_SponsorshipSet": "Sponsorship Set", + "transaction_type_name_SponsorshipTransfer": "Sponsorship Transfer", "transaction_type_name_TicketCreate": "Ticket Create", "transaction_type_name_TrustSet": "Trust Set", "transaction_type_name_VaultCreate": "Vault Create", @@ -730,6 +732,12 @@ "account_page_payment_channels": "Payment Channels", "account_page_payment_channels_text": "{{currency}} available in {{number}} channel(s)", "account_page_nft_minter": "NFT Minter", + "account_page_sponsored_fees_reserves_title": "Sponsored Fees & Reserves", + "account_page_sponsored_scope": "Scope", + "account_page_sponsored_by": "Sponsored by", + "account_page_sponsored_scope_transaction_fees": "Transaction Fees", + "account_page_sponsored_scope_base_reserve": "Base Reserve", + "account_page_sponsored_none": "No Sponsors", "account_page_asset_held_title": "Assets Held", "account_page_asset_issued_title": "Assets Issued", "account_page_asset_tab_iou": "IOUs ({{count}})", @@ -946,5 +954,30 @@ "registered": "Registered", "included": "Included", "maintenance_banner.notice": "Scheduled maintenance: {{window}} (~{{duration}} min downtime).", - "maintenance_banner.countdown_prefix": "Starts in" + "maintenance_banner.countdown_prefix": "Starts in", + "sponsor": "Sponsor", + "sponsee": "Sponsee", + "new_sponsor": "New Sponsor", + "fee_amount_delta": "Fee Amount Change", + "max_fee": "Max Fee", + "reserve_count_delta": "Reserve Count Change", + "require_sign_for_fee": "Require Sign For Fee", + "require_sign_for_reserve": "Require Sign For Reserve", + "sponsorship_deleted": "Sponsorship Deleted", + "operation": "Operation", + "object_id": "Object ID", + "sponsorship_operation_create": "Create", + "sponsorship_operation_reassign": "Reassign", + "sponsorship_operation_end": "End", + "sponsorship_set_description_fee": " sponsors transaction fees for ", + "sponsorship_set_description_reserve": " sponsors reserves for ", + "sponsorship_set_description_fee_reserve": " sponsors transaction fees and reserves for ", + "sponsorship_set_description_generic": " updates its sponsorship terms for ", + "sponsorship_set_delete": " ends the fee sponsorship for ", + "sponsorship_transfer_create": " assigns as its reserve sponsor", + "sponsorship_transfer_reassign": " reassigns reserve sponsorship to ", + "sponsorship_transfer_end_other": " ends reserve sponsorship for ", + "sponsorship_transfer_end_self": " ends its reserve sponsorship", + "sponsor_detail": " is sponsoring this transaction", + "sponsor_co_signed": "The sponsor co-signed this transaction" } diff --git a/public/locales/es-ES/translations.json b/public/locales/es-ES/translations.json index 12e1a48f4..b2ac260d6 100644 --- a/public/locales/es-ES/translations.json +++ b/public/locales/es-ES/translations.json @@ -209,6 +209,8 @@ "transaction_type_name_SetHook": "Añadir Hook", "transaction_type_name_SetRegularKey": "Configurar Clave Normal", "transaction_type_name_SignerListSet": "Configurar Lista de Firmantes", + "transaction_type_name_SponsorshipSet": null, + "transaction_type_name_SponsorshipTransfer": null, "transaction_type_name_TicketCreate": "Creación de Ticket", "transaction_type_name_TrustSet": "Configurar Confianza", "transaction_type_name_VaultCreate": null, diff --git a/public/locales/fr-FR/translations.json b/public/locales/fr-FR/translations.json index 99bb71f9e..64d716b88 100644 --- a/public/locales/fr-FR/translations.json +++ b/public/locales/fr-FR/translations.json @@ -209,6 +209,8 @@ "transaction_type_name_SetHook": "Crochet enregistré", "transaction_type_name_SetRegularKey": "Clé régulière définie", "transaction_type_name_SignerListSet": "Liste de signataires établie", + "transaction_type_name_SponsorshipSet": null, + "transaction_type_name_SponsorshipTransfer": null, "transaction_type_name_TicketCreate": "Ticket créé", "transaction_type_name_TrustSet": "Ligne de confiance créée", "transaction_type_name_VaultCreate": null, diff --git a/public/locales/ja-JP/translations.json b/public/locales/ja-JP/translations.json index 8229d9e98..f8b78782d 100644 --- a/public/locales/ja-JP/translations.json +++ b/public/locales/ja-JP/translations.json @@ -209,6 +209,8 @@ "transaction_type_name_SetHook": "Hookの設定", "transaction_type_name_SetRegularKey": "レギュラーキーの設定", "transaction_type_name_SignerListSet": "署名者リスト設定", + "transaction_type_name_SponsorshipSet": null, + "transaction_type_name_SponsorshipTransfer": null, "transaction_type_name_TicketCreate": "チケットの作成", "transaction_type_name_TrustSet": "トラスト設定", "transaction_type_name_VaultCreate": null, diff --git a/public/locales/ko-KR/translations.json b/public/locales/ko-KR/translations.json index d02b1dd5c..3571a6034 100644 --- a/public/locales/ko-KR/translations.json +++ b/public/locales/ko-KR/translations.json @@ -209,6 +209,8 @@ "transaction_type_name_SetHook": "Hook 설정", "transaction_type_name_SetRegularKey": "일반 키 설정", "transaction_type_name_SignerListSet": "서명자 목록 설정", + "transaction_type_name_SponsorshipSet": null, + "transaction_type_name_SponsorshipTransfer": null, "transaction_type_name_TicketCreate": "티켓 생성", "transaction_type_name_TrustSet": "신뢰 설정", "transaction_type_name_VaultCreate": null, diff --git a/public/locales/my-MM/translations.json b/public/locales/my-MM/translations.json index c1ef818ab..4a7835958 100644 --- a/public/locales/my-MM/translations.json +++ b/public/locales/my-MM/translations.json @@ -209,6 +209,8 @@ "transaction_type_name_SetHook": "Hook သတ်မှတ်ရန်", "transaction_type_name_SetRegularKey": "ပုံမှန်သော့ သတ်မှတ်ရန်", "transaction_type_name_SignerListSet": "လက်မှတ်ထိုးသူစာရင်း သတ်မှတ်ရန်", + "transaction_type_name_SponsorshipSet": null, + "transaction_type_name_SponsorshipTransfer": null, "transaction_type_name_TicketCreate": "လက်မှတ် ဖန်တီးရန်", "transaction_type_name_TrustSet": "ယုံကြည်မှု သတ်မှတ်ရန်", "transaction_type_name_VaultCreate": null, diff --git a/src/containers/Accounts/SponsoredFeesReserves/index.tsx b/src/containers/Accounts/SponsoredFeesReserves/index.tsx new file mode 100644 index 000000000..2101a74e6 --- /dev/null +++ b/src/containers/Accounts/SponsoredFeesReserves/index.tsx @@ -0,0 +1,71 @@ +import { useTranslation } from 'react-i18next' +import { Account } from '../../shared/components/Account' +import { CollapsibleSection } from '../../shared/components/CollapsibleSection' +import { EmptyMessageTableRow } from '../../shared/EmptyMessageTableRow' +import type { AccountState } from '../../../rippled/accountState' +import './styles.scss' + +interface Props { + account: AccountState +} + +type ScopeKey = + | 'account_page_sponsored_scope_transaction_fees' + | 'account_page_sponsored_scope_base_reserve' + +export const SponsoredFeesReserves = ({ account }: Props) => { + const { t } = useTranslation() + + const rows: { scopeKey: ScopeKey; sponsor: string }[] = [ + ...(account.sponsorship ?? []) + .filter(({ feeAmount }) => Number(feeAmount) > 0) + .map(({ owner }) => ({ + scopeKey: 'account_page_sponsored_scope_transaction_fees' as ScopeKey, + sponsor: owner, + })), + ...(account.info?.sponsor + ? [ + { + scopeKey: 'account_page_sponsored_scope_base_reserve' as ScopeKey, + sponsor: account.info.sponsor, + }, + ] + : []), + ] + + return ( + +
+ + + + + + + + + {rows.length === 0 ? ( + + {t('account_page_sponsored_none')} + + ) : ( + rows.map(({ scopeKey, sponsor }) => ( + + + + + )) + )} + +
{t('account_page_sponsored_scope')}{t('account_page_sponsored_by')}
{t(scopeKey)} + +
+
+
+ ) +} diff --git a/src/containers/Accounts/SponsoredFeesReserves/styles.scss b/src/containers/Accounts/SponsoredFeesReserves/styles.scss new file mode 100644 index 000000000..90251641b --- /dev/null +++ b/src/containers/Accounts/SponsoredFeesReserves/styles.scss @@ -0,0 +1,43 @@ +@use '../../shared/css/variables' as *; + +.sponsored-fees-reserves-section { + padding: 24px 0; +} + +.sponsored-fees-reserves-table-wrapper { + -webkit-overflow-scrolling: touch; + overflow-x: auto; +} + +.sponsored-fees-reserves-table { + width: 100%; + border-collapse: collapse; + + thead th { + @include semibold; + + padding: 10px 12px; + color: $black-50; + font-size: 12px; + text-align: left; + text-transform: uppercase; + } + + tbody td { + padding: 10px 12px; + border-bottom: 1px solid $black-80; + color: $white; + font-size: 14px; + + &.empty-message { + padding: 16px; + color: $black-40; + font-size: 16px; + text-align: center; + } + } + + tbody tr:first-child td { + border-top: 1px solid $black-80; + } +} diff --git a/src/containers/Accounts/SponsoredFeesReserves/test/SponsoredFeesReserves.test.tsx b/src/containers/Accounts/SponsoredFeesReserves/test/SponsoredFeesReserves.test.tsx new file mode 100644 index 000000000..9372794d9 --- /dev/null +++ b/src/containers/Accounts/SponsoredFeesReserves/test/SponsoredFeesReserves.test.tsx @@ -0,0 +1,196 @@ +import { render, screen, fireEvent } from '@testing-library/react' +import { I18nextProvider } from 'react-i18next' +import { BrowserRouter as Router } from 'react-router' +import i18n from '../../../../i18n/testConfigEnglish' +import { SponsoredFeesReserves } from '../index' +import type { AccountState } from '../../../../rippled/accountState' + +jest.mock('../../../shared/components/Account', () => ({ + Account: ({ account }: { account: string }) => ( + {account} + ), +})) + +const TestWrapper = ({ children }: { children: React.ReactNode }) => ( + + {children} + +) + +const baseAccount: AccountState = { + account: 'rAccount1111111111111111111111111', + info: { ticketCount: 0, flags: [] }, + deleted: false, +} + +const openSection = () => { + fireEvent.click( + screen.getByLabelText('Toggle sponsored fees & reserves section'), + ) +} + +describe('SponsoredFeesReserves Component', () => { + it('renders the title and starts collapsed', () => { + render( + + + , + ) + + expect(screen.getByText('Sponsored Fees & Reserves')).toBeInTheDocument() + expect(screen.queryByText('No Sponsors')).not.toBeInTheDocument() + }) + + it('shows "No Sponsors" when the account has no sponsorship', () => { + render( + + + , + ) + + openSection() + + expect(screen.getByText('No Sponsors')).toBeInTheDocument() + expect(screen.queryByText('Transaction Fees')).not.toBeInTheDocument() + expect(screen.queryByText('Base Reserve')).not.toBeInTheDocument() + }) + + it('renders only the Base Reserve row when only the reserve is sponsored', () => { + const account: AccountState = { + ...baseAccount, + info: { + ...baseAccount.info, + sponsor: 'rBaseReserveSponsor11111111111111', + }, + } + + render( + + + , + ) + + openSection() + + expect(screen.getByText('Base Reserve')).toBeInTheDocument() + expect(screen.queryByText('Transaction Fees')).not.toBeInTheDocument() + expect(screen.getByTestId('account-component')).toHaveTextContent( + 'rBaseReserveSponsor11111111111111', + ) + }) + + it('renders only the Transaction Fees row when only fees are sponsored', () => { + const account: AccountState = { + ...baseAccount, + sponsorship: [ + { + owner: 'rFeeSponsor2222222222222222222222', + sponsee: baseAccount.account, + feeAmount: '1000000', + }, + ], + } + + render( + + + , + ) + + openSection() + + expect(screen.getByText('Transaction Fees')).toBeInTheDocument() + expect(screen.queryByText('Base Reserve')).not.toBeInTheDocument() + expect(screen.getByTestId('account-component')).toHaveTextContent( + 'rFeeSponsor2222222222222222222222', + ) + }) + + it('omits the Transaction Fees row when the sponsorship has no fee budget', () => { + const account: AccountState = { + ...baseAccount, + sponsorship: [ + { + owner: 'rFeeSponsor2222222222222222222222', + sponsee: baseAccount.account, + feeAmount: '0', + }, + ], + } + + render( + + + , + ) + + openSection() + + expect(screen.getByText('No Sponsors')).toBeInTheDocument() + expect(screen.queryByText('Transaction Fees')).not.toBeInTheDocument() + }) + + it('renders both rows when both fees and reserve are sponsored', () => { + const account: AccountState = { + ...baseAccount, + info: { + ...baseAccount.info, + sponsor: 'rBaseReserveSponsor11111111111111', + }, + sponsorship: [ + { + owner: 'rFeeSponsor2222222222222222222222', + sponsee: baseAccount.account, + feeAmount: '1000000', + }, + ], + } + + render( + + + , + ) + + openSection() + + expect(screen.getByText('Transaction Fees')).toBeInTheDocument() + expect(screen.getByText('Base Reserve')).toBeInTheDocument() + expect(screen.getAllByTestId('account-component')).toHaveLength(2) + }) + + it('renders one Transaction Fees row per sponsor when there are multiple fee sponsors', () => { + const account: AccountState = { + ...baseAccount, + sponsorship: [ + { + owner: 'rFeeSponsor2222222222222222222222', + sponsee: baseAccount.account, + feeAmount: '1000000', + }, + { + owner: 'rFeeSponsor3333333333333333333333', + sponsee: baseAccount.account, + feeAmount: '2000000', + }, + ], + } + + render( + + + , + ) + + openSection() + + expect(screen.getAllByText('Transaction Fees')).toHaveLength(2) + expect(screen.getAllByTestId('account-component')).toHaveLength(2) + expect(screen.getAllByTestId('account-component')[0]).toHaveTextContent( + 'rFeeSponsor2222222222222222222222', + ) + expect(screen.getAllByTestId('account-component')[1]).toHaveTextContent( + 'rFeeSponsor3333333333333333333333', + ) + }) +}) diff --git a/src/containers/Accounts/index.tsx b/src/containers/Accounts/index.tsx index d5045011e..4b68172fd 100644 --- a/src/containers/Accounts/index.tsx +++ b/src/containers/Accounts/index.tsx @@ -15,6 +15,7 @@ import { AccountSummary } from './AccountSummary' import { useXRPToUSDRate } from '../shared/hooks/useXRPToUSDRate' import AccountAsset from './AccountAsset' import AccountHeader from './AccountHeader' +import { SponsoredFeesReserves } from './SponsoredFeesReserves' import { PermissionDelegation } from './PermissionDelegation' export const Accounts = () => { @@ -66,6 +67,7 @@ export const Accounts = () => { {showAccount && ( <> + = ({ data }) => { const { t } = useTranslation() @@ -109,6 +112,42 @@ export const DetailTab: FC<{ data: any }> = ({ data }) => { ) : null } + const renderSponsor = () => { + // On create/reassign, SponsorshipTransfer reuses the common Sponsor + // field for its own "new sponsor of the target object" meaning, not for + // co-sponsoring this outer transaction, so it's excluded from the + // generic Sponsor section there. On tfSponsorshipEnd the spec requires + // Sponsor to be omitted for that purpose, so if it's present it can + // only be genuine outer co-sponsorship. + const isNewSponsorField = + data.tx.TransactionType === 'SponsorshipTransfer' && + getOperation(data.tx.Flags || 0) !== 'end' + if (isNewSponsorField) return null + if (!data.tx.Sponsor) return null + const scopes = getSponsorScopes(data.tx.SponsorFlags) + return ( +
+
{t('sponsor')}
+
+ }} + /> +
+ {scopes.length > 0 && ( +
+ {scopes + .map((scope) => t(SPONSOR_SCOPE_LABEL_KEYS[scope])) + .join(', ')} +
+ )} + {data.tx.SponsorSignature && ( +
{t('sponsor_co_signed')}
+ )} +
+ ) + } + const renderSigners = () => data.tx.Signers ? (
@@ -128,6 +167,7 @@ export const DetailTab: FC<{ data: any }> = ({ data }) => { {renderStatus()} {renderSigners()} + {renderSponsor()} {renderFlags()} {renderFee()} diff --git a/src/containers/Transactions/SimpleTab.tsx b/src/containers/Transactions/SimpleTab.tsx index b0d7fe6de..6cd599b27 100644 --- a/src/containers/Transactions/SimpleTab.tsx +++ b/src/containers/Transactions/SimpleTab.tsx @@ -8,6 +8,7 @@ import { Simple } from './Simple' import { useLanguage } from '../shared/hooks' import { RouteLink } from '../shared/routing' import { CURRENCY_OPTIONS, XRP_BASE } from '../shared/transactionUtils' +import { getOperation } from '../shared/components/Transaction/SponsorshipTransfer/parser' import { SimpleRow } from '../shared/components/Transaction/SimpleRow' import '../shared/css/simpleTab.scss' import './simpleTab.scss' @@ -41,6 +42,7 @@ export const SimpleTab: FC<{ data: any; width: number }> = ({ sequence, ticketSequence, isHook, + sponsor, ) => ( <> = ({ )} + {sponsor && ( + + + + )} = ({ ) : 0 + // On create/reassign, SponsorshipTransfer reuses the common Sponsor field + // for its own "new sponsor of the target object" meaning, not for + // co-sponsoring this outer transaction, so it's excluded from the generic + // Sponsor row there. On tfSponsorshipEnd the spec requires Sponsor to be + // omitted for that purpose, so if it's present it can only be genuine + // outer co-sponsorship. + const isNewSponsorField = + processed.tx.TransactionType === 'SponsorshipTransfer' && + getOperation(processed.tx.Flags || 0) !== 'end' + const sponsor = isNewSponsorField ? undefined : processed.tx.Sponsor + const rowIndex = renderRowIndex( time, ledgerIndex, @@ -99,6 +117,7 @@ export const SimpleTab: FC<{ data: any; width: number }> = ({ processed.tx.Sequence, processed.tx.TicketSequence, !!processed.tx.EmitDetails, + sponsor, ) return ( diff --git a/src/containers/Transactions/test/DetailTab.test.tsx b/src/containers/Transactions/test/DetailTab.test.tsx index fb678634b..98ab0012a 100644 --- a/src/containers/Transactions/test/DetailTab.test.tsx +++ b/src/containers/Transactions/test/DetailTab.test.tsx @@ -7,6 +7,7 @@ import FailedTransaction from '../../shared/components/Transaction/SignerListSet import HookPayment from './mock_data/HookPayment.json' import EmittedPayment from './mock_data/EmittedPayment.json' import TrustSet from './mock_data/TrustSet.json' +import SponsorshipTransferCreate from '../../shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferCreate.json' import { DetailTab } from '../DetailTab' import i18n from '../../../i18n/testConfigEnglish' import { convertHexToString } from '../../../rippled/lib/utils' @@ -151,6 +152,28 @@ describe('DetailTab container', () => { expect(detailLines?.[3]).toHaveTextContent('Emitted 0 transactions') }) + it('renders a Sponsor section for a co-sponsored transaction', () => { + const sponsoredTransaction = { + ...Transaction, + tx: { + ...Transaction.tx, + Sponsor: 'rSponsor1111111111111111111111111', + SponsorFlags: 1, + }, + } + const { container } = renderDetailTab(sponsoredTransaction) + expect( + container.querySelector('[data-testid="sponsor-section"]'), + ).toBeInTheDocument() + }) + + it('does not render a Sponsor section for SponsorshipTransfer, which reuses the field for its own meaning', () => { + const { container } = renderDetailTab(SponsorshipTransferCreate) + expect( + container.querySelector('[data-testid="sponsor-section"]'), + ).not.toBeInTheDocument() + }) + it('renders flags', () => { const { container } = renderDetailTab(TrustSet) const expectedFlags = new Set([ diff --git a/src/containers/Transactions/test/SimpleTab.test.tsx b/src/containers/Transactions/test/SimpleTab.test.tsx index 05f22a133..2efd9a1ac 100644 --- a/src/containers/Transactions/test/SimpleTab.test.tsx +++ b/src/containers/Transactions/test/SimpleTab.test.tsx @@ -6,6 +6,8 @@ import { QueryClientProvider } from 'react-query' import EnableAmendment from './mock_data/EnableAmendment.json' import Payment from '../../shared/components/Transaction/Payment/test/mock_data/Payment.json' import DelegatePayment from './mock_data/DelegatePayment.json' +import SponsorshipTransferCreate from '../../shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferCreate.json' +import SponsorshipTransferEnd from '../../shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferEnd.json' import { SimpleTab } from '../SimpleTab' import summarize from '../../../rippled/lib/txSummary' import i18n from '../../../i18n/testConfig' @@ -79,4 +81,45 @@ describe('SimpleTab container', () => { expectSimpleRowText(container, 'sequence', '2947132') expectSimpleRowText(container, 'tx-cost', '\uE9000.000001') }) + + it('renders a Sponsor row for a co-sponsored transaction', () => { + const sponsoredPayment = { + ...Payment, + tx: { + ...Payment.tx, + Sponsor: 'rSponsor1111111111111111111111111', + SponsorFlags: 1, + }, + } + const { container } = renderSimpleTab(sponsoredPayment) + expectSimpleRowText( + container, + 'sponsor', + 'rSponsor1111111111111111111111111', + ) + }) + + it('does not render a Sponsor row for SponsorshipTransfer create/reassign, which reuses the field for its own meaning', () => { + const { container } = renderSimpleTab(SponsorshipTransferCreate) + expect( + container.querySelector('[data-testid="sponsor"]'), + ).not.toBeInTheDocument() + }) + + it('renders a Sponsor row for SponsorshipTransfer end, where the field is free for genuine co-sponsorship', () => { + const coSponsoredEnd = { + ...SponsorshipTransferEnd, + tx: { + ...SponsorshipTransferEnd.tx, + Sponsor: 'rSponsor1111111111111111111111111', + SponsorFlags: 1, + }, + } + const { container } = renderSimpleTab(coSponsoredEnd) + expectSimpleRowText( + container, + 'sponsor', + 'rSponsor1111111111111111111111111', + ) + }) }) diff --git a/src/containers/shared/components/Transaction/DefaultSimple.tsx b/src/containers/shared/components/Transaction/DefaultSimple.tsx index 481616688..070fc07ca 100644 --- a/src/containers/shared/components/Transaction/DefaultSimple.tsx +++ b/src/containers/shared/components/Transaction/DefaultSimple.tsx @@ -20,6 +20,9 @@ const DEFAULT_TX_ELEMENTS = [ 'NetworkID', 'Sequence', 'SigningPubKey', + 'Sponsor', + 'SponsorFlags', + 'SponsorSignature', 'TransactionType', 'TxnSignature', 'ctid', diff --git a/src/containers/shared/components/Transaction/SponsorshipSet/Description.tsx b/src/containers/shared/components/Transaction/SponsorshipSet/Description.tsx new file mode 100644 index 000000000..f40b9baad --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipSet/Description.tsx @@ -0,0 +1,44 @@ +import { Trans } from 'react-i18next' +import type { SponsorshipSet } from 'xrpl' +import { TransactionDescriptionProps } from '../types' +import { Account } from '../../Account' +import { parser } from './parser' + +function getDescriptionKey( + isDelete: boolean, + hasFeeDelta: boolean, + hasReserveDelta: boolean, +) { + if (isDelete) return 'sponsorship_set_delete' + if (hasFeeDelta && hasReserveDelta) + return 'sponsorship_set_description_fee_reserve' + if (hasReserveDelta) return 'sponsorship_set_description_reserve' + if (hasFeeDelta) return 'sponsorship_set_description_fee' + return 'sponsorship_set_description_generic' +} + +export const Description = ({ + data, +}: TransactionDescriptionProps) => { + const { + sponsor, + sponsee, + isDelete, + feeAmountDelta, + remainingOwnerCountDelta, + } = parser(data.tx) + + return ( + , + Sponsee: , + }} + /> + ) +} diff --git a/src/containers/shared/components/Transaction/SponsorshipSet/Simple.tsx b/src/containers/shared/components/Transaction/SponsorshipSet/Simple.tsx new file mode 100644 index 000000000..0d4cbe115 --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipSet/Simple.tsx @@ -0,0 +1,76 @@ +import { useTranslation } from 'react-i18next' +import { TransactionSimpleComponent, TransactionSimpleProps } from '../types' +import { SimpleRow } from '../SimpleRow' +import { Account } from '../../Account' +import { Amount } from '../../Amount' + +export const Simple: TransactionSimpleComponent = ({ + data, +}: TransactionSimpleProps) => { + const { t } = useTranslation() + const { + sponsor, + sponsee, + isDelete, + feeAmountDelta, + maxFee, + remainingOwnerCountDelta, + requireSignForFee, + requireSignForReserve, + } = data.instructions + + return ( + <> + + + + + + + {isDelete && ( + + {t('sponsorship_deleted')} + + )} + {!isDelete && feeAmountDelta && ( + + + + )} + {!isDelete && maxFee && ( + + + + )} + {!isDelete && remainingOwnerCountDelta !== undefined && ( + + {remainingOwnerCountDelta > 0 + ? `+${remainingOwnerCountDelta}` + : remainingOwnerCountDelta} + + )} + {!isDelete && requireSignForFee && ( + + {t('yes')} + + )} + {!isDelete && requireSignForReserve && ( + + {t('yes')} + + )} + + ) +} diff --git a/src/containers/shared/components/Transaction/SponsorshipSet/TableDetail.tsx b/src/containers/shared/components/Transaction/SponsorshipSet/TableDetail.tsx new file mode 100644 index 000000000..b9bf60a42 --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipSet/TableDetail.tsx @@ -0,0 +1,62 @@ +import { useTranslation } from 'react-i18next' +import { TransactionTableDetailProps } from '../types' +import { Account } from '../../Account' +import { Amount } from '../../Amount' + +export const TableDetail = ({ instructions }: TransactionTableDetailProps) => { + const { t } = useTranslation() + const { + sponsor, + sponsee, + isDelete, + feeAmountDelta, + maxFee, + remainingOwnerCountDelta, + } = instructions + + return ( +
+
+ {t('sponsor')} + +
+
+ {t('sponsee')} + +
+ {isDelete && ( +
+ {t('status')} + + {t('sponsorship_deleted')} + +
+ )} + {!isDelete && feeAmountDelta && ( +
+ {t('fee_amount_delta')} + +
+ )} + {!isDelete && maxFee && ( +
+ {t('max_fee')} + +
+ )} + {!isDelete && remainingOwnerCountDelta !== undefined && ( +
+ {t('reserve_count_delta')} + + {remainingOwnerCountDelta > 0 + ? `+${remainingOwnerCountDelta}` + : remainingOwnerCountDelta} + +
+ )} +
+ ) +} diff --git a/src/containers/shared/components/Transaction/SponsorshipSet/index.ts b/src/containers/shared/components/Transaction/SponsorshipSet/index.ts new file mode 100644 index 000000000..ffe94a69a --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipSet/index.ts @@ -0,0 +1,18 @@ +import { + TransactionAction, + TransactionCategory, + TransactionMapping, +} from '../types' +import { Simple } from './Simple' +import { Description } from './Description' +import { TableDetail } from './TableDetail' +import { parser } from './parser' + +export const SponsorshipSetTransaction: TransactionMapping = { + Description, + Simple, + TableDetail, + parser, + action: TransactionAction.MODIFY, + category: TransactionCategory.ACCOUNT, +} diff --git a/src/containers/shared/components/Transaction/SponsorshipSet/parser.ts b/src/containers/shared/components/Transaction/SponsorshipSet/parser.ts new file mode 100644 index 000000000..148bd85aa --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipSet/parser.ts @@ -0,0 +1,40 @@ +import type { SponsorshipSet } from 'xrpl' +import { formatAmount } from '../../../../../rippled/lib/txSummary/formatAmount' + +const TF_DELETE_OBJECT = 0x00100000 +const TF_SET_REQUIRE_SIGN_FOR_FEE = 0x00010000 +const TF_SET_REQUIRE_SIGN_FOR_RESERVE = 0x00040000 + +// Signs the formatted delta amount explicitly, since a negative amount +// (a withdrawal) would otherwise read identically to a positive one at a +// glance in the UI. +function getSignedDelta(delta: string | undefined) { + if (delta === undefined) return undefined + const formatted = formatAmount(delta) + const amount = Number(formatted.amount) + return { + value: { ...formatted, amount: Math.abs(amount) }, + modifier: amount < 0 ? ('-' as const) : ('+' as const), + } +} + +export function parser(tx: SponsorshipSet) { + const flags = typeof tx.Flags === 'number' ? tx.Flags : 0 + // If CounterpartySponsor is given, this account is the sponsee; if Sponsee + // is given, this account is the sponsor. + const sponsor = tx.CounterpartySponsor ?? tx.Account + const sponsee = tx.Sponsee ?? tx.Account + + return { + sponsor, + sponsee, + isDelete: Boolean(flags & TF_DELETE_OBJECT), + feeAmountDelta: getSignedDelta(tx.FeeAmountDelta), + maxFee: tx.MaxFee !== undefined ? formatAmount(tx.MaxFee) : undefined, + remainingOwnerCountDelta: tx.RemainingOwnerCountDelta, + requireSignForFee: + Boolean(flags & TF_SET_REQUIRE_SIGN_FOR_FEE) || undefined, + requireSignForReserve: + Boolean(flags & TF_SET_REQUIRE_SIGN_FOR_RESERVE) || undefined, + } +} diff --git a/src/containers/shared/components/Transaction/SponsorshipSet/test/SponsorshipSetDescription.test.tsx b/src/containers/shared/components/Transaction/SponsorshipSet/test/SponsorshipSetDescription.test.tsx new file mode 100644 index 000000000..7619b8bec --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipSet/test/SponsorshipSetDescription.test.tsx @@ -0,0 +1,70 @@ +import i18n from '../../../../../../i18n/testConfigEnglish' +import { createDescriptionRenderFactory } from '../../test' +import { Description } from '../Description' +import SponsorshipSet from './mock_data/SponsorshipSet.json' +import SponsorshipSetDelete from './mock_data/SponsorshipSetDelete.json' + +const renderComponent = createDescriptionRenderFactory(Description, i18n) + +const SPONSOR = 'rFeeSponsorAlpha11111111111111111' +const SPONSEE = 'rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM' + +describe('SponsorshipSet: Description', () => { + it('describes fee and reserve sponsorship being set together', () => { + const { container, unmount } = renderComponent(SponsorshipSet) + expect(container).toHaveTextContent( + `${SPONSOR} sponsors transaction fees and reserves for ${SPONSEE}`, + ) + unmount() + }) + + it('describes only fee sponsorship being set', () => { + const { container, unmount } = renderComponent({ + tx: { + Account: SPONSOR, + Sponsee: SPONSEE, + FeeAmountDelta: '1000000', + }, + }) + expect(container).toHaveTextContent( + `${SPONSOR} sponsors transaction fees for ${SPONSEE}`, + ) + unmount() + }) + + it('describes only reserve sponsorship being set', () => { + const { container, unmount } = renderComponent({ + tx: { + Account: SPONSOR, + Sponsee: SPONSEE, + RemainingOwnerCountDelta: 5, + }, + }) + expect(container).toHaveTextContent( + `${SPONSOR} sponsors reserves for ${SPONSEE}`, + ) + unmount() + }) + + it('falls back to a generic description when neither delta is present', () => { + const { container, unmount } = renderComponent({ + tx: { + Account: SPONSOR, + Sponsee: SPONSEE, + MaxFee: '1000', + }, + }) + expect(container).toHaveTextContent( + `${SPONSOR} updates its sponsorship terms for ${SPONSEE}`, + ) + unmount() + }) + + it('describes a fee sponsorship being ended', () => { + const { container, unmount } = renderComponent(SponsorshipSetDelete) + expect(container).toHaveTextContent( + `${SPONSOR} ends the fee sponsorship for ${SPONSEE}`, + ) + unmount() + }) +}) diff --git a/src/containers/shared/components/Transaction/SponsorshipSet/test/SponsorshipSetSimple.test.tsx b/src/containers/shared/components/Transaction/SponsorshipSet/test/SponsorshipSetSimple.test.tsx new file mode 100644 index 000000000..20892f5f9 --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipSet/test/SponsorshipSetSimple.test.tsx @@ -0,0 +1,38 @@ +import { createSimpleRenderFactory, expectSimpleRowText } from '../../test' +import { Simple } from '../Simple' +import i18n from '../../../../../../i18n/testConfigEnglish' +import SponsorshipSet from './mock_data/SponsorshipSet.json' +import SponsorshipSetDelete from './mock_data/SponsorshipSetDelete.json' + +const renderComponent = createSimpleRenderFactory(Simple, i18n) + +describe('SponsorshipSet: Simple', () => { + it('renders fee sponsorship fields', () => { + const { container, unmount } = renderComponent(SponsorshipSet) + + expectSimpleRowText( + container, + 'sponsor', + 'rFeeSponsorAlpha11111111111111111', + ) + expectSimpleRowText( + container, + 'sponsee', + 'rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM', + ) + expectSimpleRowText(container, 'fee-amount-delta', '1.00 XRP') + expectSimpleRowText(container, 'max-fee', '0.001 XRP') + expectSimpleRowText(container, 'reserve-count-delta', '+5') + unmount() + }) + + it('renders deletion state without fee fields', () => { + const { container, unmount } = renderComponent(SponsorshipSetDelete) + + expectSimpleRowText(container, 'sponsorship-deleted', 'Sponsorship Deleted') + expect( + container.querySelector('[data-testid="fee-amount-delta"]'), + ).not.toBeInTheDocument() + unmount() + }) +}) diff --git a/src/containers/shared/components/Transaction/SponsorshipSet/test/SponsorshipSetTableDetail.test.tsx b/src/containers/shared/components/Transaction/SponsorshipSet/test/SponsorshipSetTableDetail.test.tsx new file mode 100644 index 000000000..92ab88755 --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipSet/test/SponsorshipSetTableDetail.test.tsx @@ -0,0 +1,44 @@ +import { createTableDetailRenderFactory } from '../../test' +import { TableDetail } from '../TableDetail' +import i18n from '../../../../../../i18n/testConfigEnglish' +import SponsorshipSet from './mock_data/SponsorshipSet.json' +import SponsorshipSetDelete from './mock_data/SponsorshipSetDelete.json' + +const renderComponent = createTableDetailRenderFactory(TableDetail, i18n) + +describe('SponsorshipSetTableDetail', () => { + it('renders fee sponsorship details', () => { + const { container, unmount } = renderComponent(SponsorshipSet) + + expect(container.querySelectorAll('.account')[0]).toHaveTextContent( + 'rFeeSponsorAlpha11111111111111111', + ) + expect(container.querySelectorAll('.account')[1]).toHaveTextContent( + 'rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM', + ) + expect( + container.querySelectorAll('[data-testid="amount"]')[0], + ).toHaveTextContent('1.00 XRP') + expect( + container.querySelectorAll('[data-testid="amount"]')[1], + ).toHaveTextContent('0.001 XRP') + expect(container.querySelector('.sponsorship-set')).toHaveTextContent( + 'Reserve Count Change+5', + ) + + unmount() + }) + + it('renders deletion state', () => { + const { container, unmount } = renderComponent(SponsorshipSetDelete) + + expect( + container.querySelector('[data-testid="sponsorship-deleted"]'), + ).toHaveTextContent('Sponsorship Deleted') + expect(container.querySelector('.sponsorship-set')).not.toHaveTextContent( + 'Fee Amount Change', + ) + + unmount() + }) +}) diff --git a/src/containers/shared/components/Transaction/SponsorshipSet/test/mock_data/SponsorshipSet.json b/src/containers/shared/components/Transaction/SponsorshipSet/test/mock_data/SponsorshipSet.json new file mode 100644 index 000000000..e906662fc --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipSet/test/mock_data/SponsorshipSet.json @@ -0,0 +1,23 @@ +{ + "hash": "A1B2C3D4E5F6070809101112131415161718192021222324252627282930313A", + "ledger_index": 46635300, + "date": "2026-08-14T13:49:23+00:00", + "tx": { + "Account": "rFeeSponsorAlpha11111111111111111", + "Sponsee": "rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM", + "FeeAmountDelta": "1000000", + "MaxFee": "1000", + "RemainingOwnerCountDelta": 5, + "Fee": "12", + "Flags": 0, + "Sequence": 42, + "SigningPubKey": "ED5063FC56A0BD4398964FFD55B3FC353C291C34B81A60BFD33FDC0B036C4D403E", + "TransactionType": "SponsorshipSet", + "TxnSignature": "E98B5560AEE64C27C680E7B9A83239DB3035958761626186455E56C841EBD88438057A0B355C9410E6E5B1A494BFE957ADD8B4873FC9D4700A3BA1041451A905" + }, + "meta": { + "AffectedNodes": [], + "TransactionIndex": 0, + "TransactionResult": "tesSUCCESS" + } +} diff --git a/src/containers/shared/components/Transaction/SponsorshipSet/test/mock_data/SponsorshipSetDelete.json b/src/containers/shared/components/Transaction/SponsorshipSet/test/mock_data/SponsorshipSetDelete.json new file mode 100644 index 000000000..1525cfa2a --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipSet/test/mock_data/SponsorshipSetDelete.json @@ -0,0 +1,20 @@ +{ + "hash": "B1B2C3D4E5F6070809101112131415161718192021222324252627282930313B", + "ledger_index": 46635301, + "date": "2026-08-14T13:49:23+00:00", + "tx": { + "Account": "rFeeSponsorAlpha11111111111111111", + "Sponsee": "rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM", + "Fee": "12", + "Flags": 1048576, + "Sequence": 43, + "SigningPubKey": "ED5063FC56A0BD4398964FFD55B3FC353C291C34B81A60BFD33FDC0B036C4D403E", + "TransactionType": "SponsorshipSet", + "TxnSignature": "E98B5560AEE64C27C680E7B9A83239DB3035958761626186455E56C841EBD88438057A0B355C9410E6E5B1A494BFE957ADD8B4873FC9D4700A3BA1041451A905" + }, + "meta": { + "AffectedNodes": [], + "TransactionIndex": 0, + "TransactionResult": "tesSUCCESS" + } +} diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/Description.tsx b/src/containers/shared/components/Transaction/SponsorshipTransfer/Description.tsx new file mode 100644 index 000000000..4b826eb59 --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/Description.tsx @@ -0,0 +1,60 @@ +import { Trans } from 'react-i18next' +import type { SponsorshipTransfer } from 'xrpl' +import { TransactionDescriptionProps } from '../types' +import { Account } from '../../Account' +import { parser } from './parser' + +export const Description = ({ + data, +}: TransactionDescriptionProps) => { + const { operation, account, sponsor, sponsee } = parser(data.tx) + + if (operation === 'create' && sponsor) { + return ( + , + Sponsor: , + }} + /> + ) + } + + if (operation === 'reassign' && sponsor) { + return ( + , + Sponsor: , + }} + /> + ) + } + + if (operation === 'end') { + if (sponsee) { + return ( + , + Sponsee: , + }} + /> + ) + } + + return ( + , + }} + /> + ) + } + + return null +} diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/Simple.tsx b/src/containers/shared/components/Transaction/SponsorshipTransfer/Simple.tsx new file mode 100644 index 000000000..f5ddb6e0c --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/Simple.tsx @@ -0,0 +1,42 @@ +import { useTranslation } from 'react-i18next' +import { TransactionSimpleComponent, TransactionSimpleProps } from '../types' +import { SimpleRow } from '../SimpleRow' +import { Account } from '../../Account' + +const OPERATION_LABEL_KEYS = { + create: 'sponsorship_operation_create', + reassign: 'sponsorship_operation_reassign', + end: 'sponsorship_operation_end', +} as const + +export const Simple: TransactionSimpleComponent = ({ + data, +}: TransactionSimpleProps) => { + const { t } = useTranslation() + const { operation, objectId, sponsor, sponsee } = data.instructions + + return ( + <> + {operation && ( + + {t(OPERATION_LABEL_KEYS[operation])} + + )} + {objectId && ( + + {objectId} + + )} + {sponsor && ( + + + + )} + {sponsee && ( + + + + )} + + ) +} diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/TableDetail.tsx b/src/containers/shared/components/Transaction/SponsorshipTransfer/TableDetail.tsx new file mode 100644 index 000000000..816be7542 --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/TableDetail.tsx @@ -0,0 +1,48 @@ +import { useTranslation } from 'react-i18next' +import { TransactionTableDetailProps } from '../types' +import { Account } from '../../Account' +import { shortenTxHash } from '../../../utils' + +const OPERATION_LABEL_KEYS = { + create: 'sponsorship_operation_create', + reassign: 'sponsorship_operation_reassign', + end: 'sponsorship_operation_end', +} as const + +export const TableDetail = ({ instructions }: TransactionTableDetailProps) => { + const { t } = useTranslation() + const { operation, objectId, sponsor, sponsee } = instructions + + return ( +
+ {operation && ( +
+ {t('operation')} + + {t(OPERATION_LABEL_KEYS[operation])} + +
+ )} + {objectId && ( +
+ {t('object_id')} + + {shortenTxHash(objectId)} + +
+ )} + {sponsor && ( +
+ {t('new_sponsor')} + +
+ )} + {sponsee && ( +
+ {t('sponsee')} + +
+ )} +
+ ) +} diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/index.ts b/src/containers/shared/components/Transaction/SponsorshipTransfer/index.ts new file mode 100644 index 000000000..df713c406 --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/index.ts @@ -0,0 +1,18 @@ +import { + TransactionAction, + TransactionCategory, + TransactionMapping, +} from '../types' +import { Simple } from './Simple' +import { Description } from './Description' +import { TableDetail } from './TableDetail' +import { parser } from './parser' + +export const SponsorshipTransferTransaction: TransactionMapping = { + Description, + Simple, + TableDetail, + parser, + action: TransactionAction.MODIFY, + category: TransactionCategory.ACCOUNT, +} diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/parser.ts b/src/containers/shared/components/Transaction/SponsorshipTransfer/parser.ts new file mode 100644 index 000000000..81e96e64c --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/parser.ts @@ -0,0 +1,26 @@ +import type { SponsorshipTransfer } from 'xrpl' + +const TF_END = 0x00010000 +const TF_CREATE = 0x00020000 +const TF_REASSIGN = 0x00040000 + +export type SponsorshipTransferOperation = 'create' | 'reassign' | 'end' + +export function getOperation( + flags: number, +): SponsorshipTransferOperation | undefined { + if (flags & TF_CREATE) return 'create' + if (flags & TF_REASSIGN) return 'reassign' + if (flags & TF_END) return 'end' + return undefined +} + +export function parser(tx: SponsorshipTransfer) { + return { + operation: getOperation(typeof tx.Flags === 'number' ? tx.Flags : 0), + account: tx.Account, + objectId: tx.ObjectID, + sponsor: tx.Sponsor, + sponsee: tx.Sponsee, + } +} diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/test/SponsorshipTransferDescription.test.tsx b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/SponsorshipTransferDescription.test.tsx new file mode 100644 index 000000000..99eec68e2 --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/SponsorshipTransferDescription.test.tsx @@ -0,0 +1,34 @@ +import i18n from '../../../../../../i18n/testConfigEnglish' +import { createDescriptionRenderFactory } from '../../test' +import { Description } from '../Description' +import SponsorshipTransferCreate from './mock_data/SponsorshipTransferCreate.json' +import SponsorshipTransferReassign from './mock_data/SponsorshipTransferReassign.json' +import SponsorshipTransferEnd from './mock_data/SponsorshipTransferEnd.json' + +const renderComponent = createDescriptionRenderFactory(Description, i18n) + +describe('SponsorshipTransfer: Description', () => { + it('describes a create operation', () => { + const { container, unmount } = renderComponent(SponsorshipTransferCreate) + expect(container).toHaveTextContent( + 'rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM assigns rBaseReserveSponsor1111111111111 as its reserve sponsor', + ) + unmount() + }) + + it('describes a reassign operation', () => { + const { container, unmount } = renderComponent(SponsorshipTransferReassign) + expect(container).toHaveTextContent( + 'rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM reassigns reserve sponsorship to rBaseReserveSponsor2222222222222', + ) + unmount() + }) + + it('describes an end operation on behalf of a sponsee', () => { + const { container, unmount } = renderComponent(SponsorshipTransferEnd) + expect(container).toHaveTextContent( + 'rBaseReserveSponsor1111111111111 ends reserve sponsorship for rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM', + ) + unmount() + }) +}) diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/test/SponsorshipTransferSimple.test.tsx b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/SponsorshipTransferSimple.test.tsx new file mode 100644 index 000000000..52f5d8aea --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/SponsorshipTransferSimple.test.tsx @@ -0,0 +1,57 @@ +import { createSimpleRenderFactory, expectSimpleRowText } from '../../test' +import { Simple } from '../Simple' +import i18n from '../../../../../../i18n/testConfigEnglish' +import SponsorshipTransferCreate from './mock_data/SponsorshipTransferCreate.json' +import SponsorshipTransferReassign from './mock_data/SponsorshipTransferReassign.json' +import SponsorshipTransferEnd from './mock_data/SponsorshipTransferEnd.json' + +const renderComponent = createSimpleRenderFactory(Simple, i18n) + +describe('SponsorshipTransfer: Simple', () => { + it('renders a create operation', () => { + const { container, unmount } = renderComponent(SponsorshipTransferCreate) + + expectSimpleRowText(container, 'operation', 'Create') + expectSimpleRowText( + container, + 'new-sponsor', + 'rBaseReserveSponsor1111111111111', + ) + expect( + container.querySelector('[data-testid="object-id"]'), + ).not.toBeInTheDocument() + unmount() + }) + + it('renders a reassign operation with an object id', () => { + const { container, unmount } = renderComponent(SponsorshipTransferReassign) + + expectSimpleRowText(container, 'operation', 'Reassign') + expectSimpleRowText( + container, + 'object-id', + '04F57D5C7F5B660C187BB55227DFC703AEFE482AEA8EEAF4C7FA5ED9BFF3403E', + ) + expectSimpleRowText( + container, + 'new-sponsor', + 'rBaseReserveSponsor2222222222222', + ) + unmount() + }) + + it('renders an end operation with the sponsee', () => { + const { container, unmount } = renderComponent(SponsorshipTransferEnd) + + expectSimpleRowText(container, 'operation', 'End') + expectSimpleRowText( + container, + 'sponsee', + 'rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM', + ) + expect( + container.querySelector('[data-testid="new-sponsor"]'), + ).not.toBeInTheDocument() + unmount() + }) +}) diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/test/SponsorshipTransferTableDetail.test.tsx b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/SponsorshipTransferTableDetail.test.tsx new file mode 100644 index 000000000..7c12017cf --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/SponsorshipTransferTableDetail.test.tsx @@ -0,0 +1,33 @@ +import { createTableDetailRenderFactory } from '../../test' +import { TableDetail } from '../TableDetail' +import i18n from '../../../../../../i18n/testConfigEnglish' +import SponsorshipTransferCreate from './mock_data/SponsorshipTransferCreate.json' +import SponsorshipTransferReassign from './mock_data/SponsorshipTransferReassign.json' + +const renderComponent = createTableDetailRenderFactory(TableDetail, i18n) + +describe('SponsorshipTransferTableDetail', () => { + it('renders a create operation', () => { + const { container, unmount } = renderComponent(SponsorshipTransferCreate) + + expect( + container.querySelector('[data-testid="operation"]'), + ).toHaveTextContent('Create') + expect(container.querySelectorAll('.account')[0]).toHaveTextContent( + 'rBaseReserveSponsor1111111111111', + ) + unmount() + }) + + it('renders a reassign operation with a shortened object id', () => { + const { container, unmount } = renderComponent(SponsorshipTransferReassign) + + expect( + container.querySelector('[data-testid="operation"]'), + ).toHaveTextContent('Reassign') + expect( + container.querySelector('[data-testid="object-id"]'), + ).toHaveTextContent('04F57D...F3403E') + unmount() + }) +}) diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferCreate.json b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferCreate.json new file mode 100644 index 000000000..b4ad9cc9f --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferCreate.json @@ -0,0 +1,21 @@ +{ + "hash": "C1B2C3D4E5F6070809101112131415161718192021222324252627282930313C", + "ledger_index": 46635302, + "date": "2026-08-14T13:49:23+00:00", + "tx": { + "Account": "rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM", + "Sponsor": "rBaseReserveSponsor1111111111111", + "SponsorFlags": 2, + "Fee": "12", + "Flags": 131072, + "Sequence": 44, + "SigningPubKey": "ED5063FC56A0BD4398964FFD55B3FC353C291C34B81A60BFD33FDC0B036C4D403E", + "TransactionType": "SponsorshipTransfer", + "TxnSignature": "E98B5560AEE64C27C680E7B9A83239DB3035958761626186455E56C841EBD88438057A0B355C9410E6E5B1A494BFE957ADD8B4873FC9D4700A3BA1041451A905" + }, + "meta": { + "AffectedNodes": [], + "TransactionIndex": 0, + "TransactionResult": "tesSUCCESS" + } +} diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferEnd.json b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferEnd.json new file mode 100644 index 000000000..f27d41868 --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferEnd.json @@ -0,0 +1,20 @@ +{ + "hash": "E1B2C3D4E5F6070809101112131415161718192021222324252627282930313E", + "ledger_index": 46635304, + "date": "2026-08-14T13:49:23+00:00", + "tx": { + "Account": "rBaseReserveSponsor1111111111111", + "Sponsee": "rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM", + "Fee": "12", + "Flags": 65536, + "Sequence": 46, + "SigningPubKey": "ED5063FC56A0BD4398964FFD55B3FC353C291C34B81A60BFD33FDC0B036C4D403E", + "TransactionType": "SponsorshipTransfer", + "TxnSignature": "E98B5560AEE64C27C680E7B9A83239DB3035958761626186455E56C841EBD88438057A0B355C9410E6E5B1A494BFE957ADD8B4873FC9D4700A3BA1041451A905" + }, + "meta": { + "AffectedNodes": [], + "TransactionIndex": 0, + "TransactionResult": "tesSUCCESS" + } +} diff --git a/src/containers/shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferReassign.json b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferReassign.json new file mode 100644 index 000000000..98c3ee378 --- /dev/null +++ b/src/containers/shared/components/Transaction/SponsorshipTransfer/test/mock_data/SponsorshipTransferReassign.json @@ -0,0 +1,22 @@ +{ + "hash": "D1B2C3D4E5F6070809101112131415161718192021222324252627282930313D", + "ledger_index": 46635303, + "date": "2026-08-14T13:49:23+00:00", + "tx": { + "Account": "rncKvRcdDq9hVJpdLdTcKoxsS3NSkXsvfM", + "ObjectID": "04F57D5C7F5B660C187BB55227DFC703AEFE482AEA8EEAF4C7FA5ED9BFF3403E", + "Sponsor": "rBaseReserveSponsor2222222222222", + "SponsorFlags": 2, + "Fee": "12", + "Flags": 262144, + "Sequence": 45, + "SigningPubKey": "ED5063FC56A0BD4398964FFD55B3FC353C291C34B81A60BFD33FDC0B036C4D403E", + "TransactionType": "SponsorshipTransfer", + "TxnSignature": "E98B5560AEE64C27C680E7B9A83239DB3035958761626186455E56C841EBD88438057A0B355C9410E6E5B1A494BFE957ADD8B4873FC9D4700A3BA1041451A905" + }, + "meta": { + "AffectedNodes": [], + "TransactionIndex": 0, + "TransactionResult": "tesSUCCESS" + } +} diff --git a/src/containers/shared/components/Transaction/index.ts b/src/containers/shared/components/Transaction/index.ts index 42ff43b4d..8a4faf61a 100644 --- a/src/containers/shared/components/Transaction/index.ts +++ b/src/containers/shared/components/Transaction/index.ts @@ -38,6 +38,8 @@ import { SetFeeTransaction as SetFee } from './SetFee' import { SetHookTransaction as SetHook } from './SetHook' import { SetRegularKeyTransaction as SetRegularKey } from './SetRegularKey' import { SignerListSetTransaction as SignerListSet } from './SignerListSet' +import { SponsorshipSetTransaction as SponsorshipSet } from './SponsorshipSet' +import { SponsorshipTransferTransaction as SponsorshipTransfer } from './SponsorshipTransfer' import { XChainAccountCreateCommitTransaction as XChainAccountCreateCommit } from './XChainAccountCreateCommit' import { XChainAddAccountCreateAttestationTransaction as XChainAddAccountCreateAttestation } from './XChainAddAccountCreateAttestation' import { XChainAddClaimAttestationTransaction as XChainAddClaimAttestation } from './XChainAddClaimAttestation' @@ -120,6 +122,8 @@ export const transactionTypes: { [key: string]: TransactionMapping } = { SetHook, SetRegularKey, SignerListSet, + SponsorshipSet, + SponsorshipTransfer, XChainAccountCreateCommit, XChainAddAccountCreateAttestation, XChainAddClaimAttestation, diff --git a/src/containers/shared/transactionUtils.ts b/src/containers/shared/transactionUtils.ts index 6b3c4900c..a1532d110 100644 --- a/src/containers/shared/transactionUtils.ts +++ b/src/containers/shared/transactionUtils.ts @@ -13,6 +13,27 @@ export const XRP_BASE = 1000000 export const hexMatch = /^(0x)?[0-9A-Fa-f]+$/ export const ACCOUNT_ZERO = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp' +// Common `SponsorFlags` values (also reused by SponsorshipTransfer.SponsorFlags) +const SPF_SPONSOR_FEE = 0x00000001 +const SPF_SPONSOR_RESERVE = 0x00000002 + +export type SponsorScope = 'fee' | 'reserve' + +export const getSponsorScopes = ( + sponsorFlags: number | undefined, +): SponsorScope[] => { + const flags = sponsorFlags || 0 + const scopes: SponsorScope[] = [] + if (flags & SPF_SPONSOR_FEE) scopes.push('fee') + if (flags & SPF_SPONSOR_RESERVE) scopes.push('reserve') + return scopes +} + +export const SPONSOR_SCOPE_LABEL_KEYS = { + fee: 'account_page_sponsored_scope_transaction_fees', + reserve: 'account_page_sponsored_scope_base_reserve', +} as const + export const TX_FLAGS: Record> = { all: { 0x80000000: 'tfFullyCanonicalSig', @@ -50,6 +71,18 @@ export const TX_FLAGS: Record> = { LoanSet: { 0x00010000: 'tfLoanOverpayment', }, + SponsorshipSet: { + 0x00010000: 'tfSponsorshipSetRequireSignForFee', + 0x00020000: 'tfSponsorshipClearRequireSignForFee', + 0x00040000: 'tfSponsorshipSetRequireSignForReserve', + 0x00080000: 'tfSponsorshipClearRequireSignForReserve', + 0x00100000: 'tfDeleteObject', + }, + SponsorshipTransfer: { + 0x00010000: 'tfSponsorshipEnd', + 0x00020000: 'tfSponsorshipCreate', + 0x00040000: 'tfSponsorshipReassign', + }, LoanManage: { 0x00010000: 'tfLoanDefault', 0x00020000: 'tfLoanImpair', @@ -97,6 +130,7 @@ export const TX_FLAGS: Record> = { 0x00010000: 'tfNoDirectRipple', 0x00020000: 'tfPartialPayment', 0x00040000: 'tfLimitQuality', + 0x00080000: 'tfSponsorCreatedAccount', }, PaymentChannelClaim: { 0x00010000: 'tfRenew', diff --git a/src/rippled/accountState.ts b/src/rippled/accountState.ts index 2af1d8991..4f26ac438 100644 --- a/src/rippled/accountState.ts +++ b/src/rippled/accountState.ts @@ -6,6 +6,7 @@ import { import { getAccountInfo, getAccountPaychannels, + getAccountSponsorship, getServerInfo, getAccountTransactions, } from './lib/rippled' @@ -34,6 +35,13 @@ export interface AccountState { quorum: number maxSigners: number } + sponsorship?: { + owner: string + sponsee: string + feeAmount?: string + maxFee?: string + remainingOwnerCount?: number + }[] info: { accountTransactionID?: string reserve?: number @@ -43,6 +51,7 @@ export interface AccountState { emailHash?: string flags: string[] nftMinter?: string + sponsor?: string } xAddress?: { classicAddress: string @@ -90,6 +99,7 @@ async function getAccountState( Promise.all([ getAccountPaychannels(rippledSocket, classicAddress, info.ledger_index), getServerInfo(rippledSocket), + getAccountSponsorship(rippledSocket, classicAddress, info.ledger_index), ]).then((data) => ({ account: info.Account as string, info: formatAccountInfo(info, data[1].info.validated_ledger), @@ -97,6 +107,7 @@ async function getAccountState( ? formatSignerList(info.signer_lists[0]) : undefined, paychannels: data[1], + sponsorship: data[2], xAddress: decomposedAddress || undefined, deleted: false, })), diff --git a/src/rippled/lib/rippled.ts b/src/rippled/lib/rippled.ts index 487b6f380..174043b2d 100644 --- a/src/rippled/lib/rippled.ts +++ b/src/rippled/lib/rippled.ts @@ -27,6 +27,14 @@ const formatPaychannel = (d: any) => ({ settleDelay: d.SettleDelay, }) +const formatSponsorship = (d: any) => ({ + owner: d.Owner, + sponsee: d.Sponsee, + feeAmount: d.FeeAmount, + maxFee: d.MaxFee, + remainingOwnerCount: d.RemainingOwnerCount, +}) + const executeQuery = async ( rippledSocket: XrplClient, params: any, @@ -366,6 +374,67 @@ const getAccountBridges = async ( return undefined } +// `limit` on account_objects bounds how many objects rippled examines per +// page, not how many `type`-filtered objects are returned, so a sponsee's +// Sponsorship objects could be missed entirely if only the first page were +// read. Page through via `marker` until either everything has been examined +// or a safety cap is hit. +const SPONSORSHIP_PAGE_SIZE = 400 +const SPONSORSHIP_MAX_EXAMINED = 4000 + +// get the sponsorship covering this account's fees/reserves, if any +const getAccountSponsorship = async ( + rippledSocket: ExplorerXrplClient, + account: string, + ledgerIndex: string | number = 'validated', +): Promise => { + const found: any[] = [] + + const fetchPage = async ( + marker: any, + examined: number, + ): Promise => { + const resp = await query(rippledSocket, { + command: 'account_objects', + account, + ledger_index: ledgerIndex, + type: 'sponsorship', + limit: SPONSORSHIP_PAGE_SIZE, + marker, + }) + if (resp.error === 'actNotFound') { + throw new Error('account not found', 404) + } + if (resp.error === 'invalidParams') { + // thrown when the Sponsorship amendment is not activated + // TODO: remove this when XLS-68 is live in mainnet + return undefined + } + if (resp.error_message) { + throw new Error(resp.error_message, 500) + } + + // A Sponsorship object is linked into both the sponsor's and sponsee's + // owner directories, so only keep the ones where this account is sponsored. + found.push( + ...resp.account_objects.filter((d: any) => d.Sponsee === account), + ) + + const totalExamined = examined + resp.account_objects.length + if (resp.marker && totalExamined < SPONSORSHIP_MAX_EXAMINED) { + return fetchPage(resp.marker, totalExamined) + } + return found + } + + const result = await fetchPage(undefined, 0) + if (result === undefined) { + return undefined + } + + return found.length ? found.map(formatSponsorship) : undefined +} + // get Token balance summary const getBalances = async ( rippledSocket: ExplorerXrplClient, @@ -929,6 +998,7 @@ export { getAccountEscrows, getAccountPaychannels, getAccountBridges, + getAccountSponsorship, getAccountNFTs, getAccountObjects, getNFTsIssuedByAccount, diff --git a/src/rippled/lib/test/rippled.test.ts b/src/rippled/lib/test/rippled.test.ts index e12d5303f..54fbd8faf 100644 --- a/src/rippled/lib/test/rippled.test.ts +++ b/src/rippled/lib/test/rippled.test.ts @@ -3,6 +3,7 @@ import { getLoanBroker, getMPTIssuance, getNegativeUNL, + getAccountSponsorship, } from '../rippled' const VAULT_INDEX = @@ -226,3 +227,141 @@ describe('getNegativeUNL', () => { await expect(getNegativeUNL(socket)).resolves.toEqual([]) }) }) + +describe('getAccountSponsorship', () => { + const ACCOUNT = 'rSponsee11111111111111111111111111' + const SPONSOR = 'rSponsor2222222222222222222222222' + + it('returns the formatted sponsorship when this account is the sponsee', async () => { + const socket = makeSocket({ + account_objects: [ + { + LedgerEntryType: 'Sponsorship', + Owner: SPONSOR, + Sponsee: ACCOUNT, + FeeAmount: '1000', + MaxFee: '5000', + RemainingOwnerCount: 2, + }, + ], + }) + + await expect(getAccountSponsorship(socket, ACCOUNT)).resolves.toEqual([ + { + owner: SPONSOR, + sponsee: ACCOUNT, + feeAmount: '1000', + maxFee: '5000', + remainingOwnerCount: 2, + }, + ]) + expect(socket.send).toHaveBeenCalledWith({ + command: 'account_objects', + account: ACCOUNT, + ledger_index: 'validated', + type: 'sponsorship', + limit: 400, + }) + }) + + it('returns all sponsorships when this account has multiple sponsors', async () => { + const SPONSOR_2 = 'rSponsor3333333333333333333333333' + const socket = makeSocket({ + account_objects: [ + { + LedgerEntryType: 'Sponsorship', + Owner: SPONSOR, + Sponsee: ACCOUNT, + FeeAmount: '1000', + }, + { + LedgerEntryType: 'Sponsorship', + Owner: SPONSOR_2, + Sponsee: ACCOUNT, + FeeAmount: '2000', + }, + ], + }) + + await expect(getAccountSponsorship(socket, ACCOUNT)).resolves.toEqual([ + { owner: SPONSOR, sponsee: ACCOUNT, feeAmount: '1000' }, + { owner: SPONSOR_2, sponsee: ACCOUNT, feeAmount: '2000' }, + ]) + }) + + it('pages through account_objects via marker to find sponsorships past the first page', async () => { + const socket = { + send: jest + .fn() + .mockResolvedValueOnce({ + account_objects: [], + marker: 'page-2', + }) + .mockResolvedValueOnce({ + account_objects: [ + { + LedgerEntryType: 'Sponsorship', + Owner: SPONSOR, + Sponsee: ACCOUNT, + FeeAmount: '1000', + }, + ], + }), + } as any + + await expect(getAccountSponsorship(socket, ACCOUNT)).resolves.toEqual([ + { owner: SPONSOR, sponsee: ACCOUNT, feeAmount: '1000' }, + ]) + expect(socket.send).toHaveBeenCalledTimes(2) + expect(socket.send).toHaveBeenNthCalledWith(2, { + command: 'account_objects', + account: ACCOUNT, + ledger_index: 'validated', + type: 'sponsorship', + limit: 400, + marker: 'page-2', + }) + }) + + it('ignores Sponsorship objects where this account is the sponsor, not the sponsee', async () => { + const socket = makeSocket({ + account_objects: [ + { + LedgerEntryType: 'Sponsorship', + Owner: ACCOUNT, + Sponsee: 'rSomeoneElse33333333333333333333', + FeeAmount: '1000', + }, + ], + }) + + await expect( + getAccountSponsorship(socket, ACCOUNT), + ).resolves.toBeUndefined() + }) + + it('returns undefined when the account has no sponsorship objects', async () => { + const socket = makeSocket({ account_objects: [] }) + + await expect( + getAccountSponsorship(socket, ACCOUNT), + ).resolves.toBeUndefined() + }) + + it('returns undefined when the Sponsorship amendment is not enabled', async () => { + const socket = makeSocket({ error: 'invalidParams' }) + + await expect( + getAccountSponsorship(socket, ACCOUNT), + ).resolves.toBeUndefined() + }) + + it('throws when the account is not found', async () => { + const socket = makeSocket({ error: 'actNotFound' }) + + await expect(getAccountSponsorship(socket, ACCOUNT)).rejects.toMatchObject({ + message: 'account not found', + code: 404, + }) + }) +}) diff --git a/src/rippled/lib/utils.ts b/src/rippled/lib/utils.ts index 823870688..e37e25220 100644 --- a/src/rippled/lib/utils.ts +++ b/src/rippled/lib/utils.ts @@ -125,6 +125,7 @@ interface AccountInfo { PreviousTxnID: string PreviousTxnLgrSeq: number NFTokenMinter?: string + Sponsor?: string } interface ServerInfoValidated { @@ -147,6 +148,7 @@ interface FormattedAccountInfo { previousTxn: string previousLedger: number nftMinter?: string + sponsor?: string } const formatAccountInfo = ( @@ -171,6 +173,7 @@ const formatAccountInfo = ( previousTxn: info.PreviousTxnID, previousLedger: info.PreviousTxnLgrSeq, nftMinter: info.NFTokenMinter, + sponsor: info.Sponsor, }) const formatTransaction = (tx: any): any => {