diff --git a/.gitignore b/.gitignore index ed88794..c6a5a4a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ /captures .externalNativeBuild .cxx +/.kotlin/ diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock new file mode 100644 index 0000000..b12c3bd --- /dev/null +++ b/kotlin-js-store/yarn.lock @@ -0,0 +1,588 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@noble/curves@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.0.tgz#f05771ef64da724997f69ee1261b2417a49522d6" + integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg== + dependencies: + "@noble/hashes" "1.4.0" + +"@noble/hashes@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + +abort-controller@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@~3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +debug@4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +escalade@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +format-util@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" + integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +mocha@10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.3.0.tgz#0e185c49e6dccf582035c05fa91084a4ff6e3fe9" + integrity sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "8.1.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +source-map-support@0.5.21: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +tweetnacl@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + +typescript@5.4.3: + version "5.4.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.3.tgz#5c6fedd4c87bee01cd7a528a30145521f8e0feff" + integrity sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/libs.versions.toml b/libs.versions.toml index 097daf4..f912633 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -32,6 +32,7 @@ coroutinesCore = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", ver coroutinesJdk8 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8", version.ref = "kotlinxCoroutines" } kermit = { module = "co.touchlab:kermit", version.ref = "kermit" } kotlin-bom = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" } +kotlinLogging = { module = "io.github.oshai:kotlin-logging", version = "6.0.9" } ktorClientContentNegotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } ktorClientCio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } ktorClientCore = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } @@ -39,11 +40,14 @@ ktorClientDarwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" ktorClientLogging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } ktorClientOkHttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } ktorClientWinHttp = { module = "io.ktor:ktor-client-winhttp", version.ref = "ktor" } +ktorClientJs = { module = "io.ktor:ktor-client-js", version.ref = "ktor" } ktorSerializationKotlinxJson = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } ktorUtils = { module = "io.ktor:ktor-utils", version.ref = "ktor" } okio = { module = "com.squareup.okio:okio", version.ref = "okio" } okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } okhttpLoggingInterceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" } +slf4j-api = { module = "org.slf4j:slf4j-api", version = "2.0.13" } +slf4j-simple = { module = "org.slf4j:slf4j-simple", version = "2.0.13" } serializationCore = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" } serializationJson = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" } skie-configurationAnnotations = { module = "co.touchlab.skie:configuration-annotations", version.ref = "skie" } diff --git a/solana-kotlin/build.gradle.kts b/solana-kotlin/build.gradle.kts index be68396..d898e2b 100644 --- a/solana-kotlin/build.gradle.kts +++ b/solana-kotlin/build.gradle.kts @@ -1,5 +1,6 @@ import co.touchlab.skie.configuration.ClassInterop import co.touchlab.skie.configuration.DefaultArgumentInterop +import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType plugins { alias(libs.plugins.kotlinMultiplatform) @@ -41,14 +42,44 @@ kotlin { mingwX64() linuxX64() + js(KotlinJsCompilerType.IR) { + browser { + compilations.all { + kotlinOptions { + sourceMap = true + sourceMapEmbedSources = "always" + } + } + testTask { + useMocha { + timeout = "60s" + } + } + } + nodejs { + compilations.all { + kotlinOptions { + sourceMap = true + sourceMapEmbedSources = "always" + } + } + } + generateTypeScriptDefinitions() + } + sourceSets { val jvmMain by getting { dependencies { implementation(libs.ktorClientOkHttp) implementation(libs.bouncyCastle) + implementation(libs.slf4j.api) + } + } + val jvmTest by getting { + dependencies { + implementation(libs.slf4j.simple) } } - val jvmTest by getting val commonMain by getting { dependencies { @@ -62,6 +93,7 @@ kotlin { implementation(libs.kermit) implementation(libs.okio) implementation(libs.skie.configurationAnnotations) + implementation(libs.kotlinLogging) } } val commonTest by getting { @@ -93,6 +125,12 @@ kotlin { implementation(libs.ktorClientWinHttp) } } + + val jsMain by getting { + dependencies { + implementation(libs.ktorClientJs) + } + } } } diff --git a/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/AssociatedTokenProgramTest.kt b/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/AssociatedTokenProgramTest.kt index 79f9386..8c6c99a 100644 --- a/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/AssociatedTokenProgramTest.kt +++ b/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/AssociatedTokenProgramTest.kt @@ -11,7 +11,6 @@ class AssociatedTokenProgramTest { fun testFindProgramAddress() { for (i in 0..1000) { val programId = randomKey().publicKey - println("programId: $programId") val seeds = listOf( "Lil'".encodeToByteArray(), @@ -21,15 +20,12 @@ class AssociatedTokenProgramTest { seeds = seeds, programId = programId, ) - println("address: $address") val created = Program.createProgramAddress( seeds = seeds + byteArrayOf(address.nonce.toByte()), programId = programId, ) - println("created: $created") - assertEquals(address.address, created) } } @@ -46,7 +42,6 @@ class AssociatedTokenProgramTest { val wallet = PublicKey.fromBase58(wallet) val associated = wallet.associatedTokenAddress(mint) - println(associated) val expectedAssociated = PublicKey.fromBase58(expectedAssociated) diff --git a/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/SystemProgramTest.kt b/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/SystemProgramTest.kt index e7e3ab7..4e98e37 100644 --- a/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/SystemProgramTest.kt +++ b/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/SystemProgramTest.kt @@ -1,40 +1,128 @@ package net.avianlabs.solana.domain.program -import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking +import io.github.oshai.kotlinlogging.KotlinLogging +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.test.runTest import net.avianlabs.solana.SolanaClient import net.avianlabs.solana.client.RpcKtorClient import net.avianlabs.solana.domain.core.Commitment import net.avianlabs.solana.domain.core.Transaction import net.avianlabs.solana.domain.core.TransactionBuilder -import net.avianlabs.solana.domain.core.decode import net.avianlabs.solana.methods.* import net.avianlabs.solana.tweetnacl.TweetNaCl +import net.avianlabs.solana.tweetnacl.ed25519.Ed25519Keypair import kotlin.random.Random import kotlin.test.Ignore import kotlin.test.Test -import kotlin.time.Duration.Companion.seconds + +private val logger = KotlinLogging.logger { } class SystemProgramTest { - @Test @Ignore - fun testCreateDurableNonceAccount() = runBlocking { + @Test + fun testCreateDurableNonceAccount() = runTest { val client = SolanaClient(client = RpcKtorClient("http://localhost:8899")) + val owner = TweetNaCl.Signature.generateKey(Random.nextBytes(32)) + logger.info { "Keypair: ${owner.publicKey}" } + val nonce1 = TweetNaCl.Signature.generateKey(Random.nextBytes(32)) + logger.info { "Nonce account 1: ${nonce1.publicKey}" } + val nonce2 = TweetNaCl.Signature.generateKey(Random.nextBytes(32)) + logger.info { "Nonce account 2: ${nonce2.publicKey}" } + val destination = TweetNaCl.Signature.generateKey(Random.nextBytes(32)) + logger.info { "Destination: ${destination.publicKey}" } + + val airdrop = client.requestAirdrop(owner.publicKey, 2_000_000_000) + val airdrop2 = client.requestAirdrop(destination.publicKey, 2_000_000_000) + client.waitForTransaction(airdrop, airdrop2) + + val balance = client.getBalance(owner.publicKey) + logger.info { "Balance: $balance" } + + val nonce1tx = client.createNonceAccountSigned( + keypair = owner, + nonceAccount = nonce1, + ) + val init1Sig = client.sendTransaction(nonce1tx) + + logger.info { "Initialized nonce account 1: $init1Sig" } + + val nonce2tx = client.createNonceAccountSigned( + keypair = owner, + nonceAccount = nonce2, + ) + + val init2Sig = client.sendTransaction(nonce2tx) + + logger.info { "Initialized nonce account 2: $init2Sig" } + + client.waitForTransaction(init1Sig, init2Sig) - val keypair = TweetNaCl.Signature.generateKey(Random.nextBytes(32)) - println("Keypair: ${keypair.publicKey}") - val nonceAccount = TweetNaCl.Signature.generateKey(Random.nextBytes(32)) - println("Nonce account: ${nonceAccount.publicKey}") + val nonceAccount1 = client.getNonce(nonce1.publicKey, Commitment.Confirmed) + logger.info { "Nonce account 1 info: $nonceAccount1" } - client.requestAirdrop(keypair.publicKey, 2_000_000_000) - delay(15.seconds) - val balance = client.getBalance(keypair.publicKey) - println("Balance: $balance") + val tx1 = transferTransaction( + nonceKeypair = nonce1, + owner = owner, + destination = destination, + nonceAccount = nonceAccount1, + ) - val rentExempt = client.getMinimumBalanceForRentExemption(SystemProgram.NONCE_ACCOUNT_LENGTH) + val nonceAccount2 = client.getNonce(nonce2.publicKey, Commitment.Confirmed) + logger.info { "Nonce account 2 info: $nonceAccount2" } + + val tx2 = transferTransaction( + nonceKeypair = nonce2, + owner = owner, + destination = destination, + nonceAccount = nonceAccount2, + ) + + val tx2Sig = client.sendTransaction(tx2) + + client.waitForTransaction(tx2Sig) + + val tx1Sig = client.sendTransaction(tx1) + logger.info { "Advanced nonce account: $tx1Sig" } + + client.waitForTransaction(tx1Sig) + + val newNonce = client.getNonce(nonce1.publicKey, Commitment.Confirmed) + logger.info { "New nonce: ${newNonce?.nonce}" } + } + + private fun transferTransaction( + nonceKeypair: Ed25519Keypair, + owner: Ed25519Keypair, + destination: Ed25519Keypair, + nonceAccount: NonceAccount? + ) = TransactionBuilder() + .addInstruction( + SystemProgram.nonceAdvance( + nonceAccount = nonceKeypair.publicKey, + authorized = owner.publicKey, + ) + ) + .addInstruction( + SystemProgram.transfer( + fromPublicKey = owner.publicKey, + toPublicKey = destination.publicKey, + lamports = 1_000, + ) + ) + .setRecentBlockHash(nonceAccount!!.nonce) + .build() + .sign(owner) - val blockhash = client.getRecentBlockhash() + private suspend fun SolanaClient.createNonceAccountSigned( + keypair: Ed25519Keypair, + nonceAccount: Ed25519Keypair + ): Transaction { + val rentExempt = getMinimumBalanceForRentExemption(SystemProgram.NONCE_ACCOUNT_LENGTH) + + val blockhash = getRecentBlockhash() val initTransaction = Transaction() .addInstruction( @@ -53,46 +141,21 @@ class SystemProgramTest { ) .setRecentBlockHash(blockhash.blockhash) .sign(listOf(keypair, nonceAccount)) + return initTransaction + } - - val initSignature = client.sendTransaction(initTransaction) - - println("Initialized nonce account: $initSignature") - delay(15.seconds) - - val lamportsPerSignature = client.getFeeForMessage(initTransaction.message.serialize()) - println("Lamports per signature: $lamportsPerSignature") - - val nonce = client.getNonce(nonceAccount.publicKey, Commitment.Processed) - println("Nonce account info: $nonce") - - val testTransaction = TransactionBuilder() - .addInstruction( - SystemProgram.nonceAdvance( - nonceAccount = nonceAccount.publicKey, - authorized = keypair.publicKey, - ) - ) - .addInstruction( - SystemProgram.transfer( - fromPublicKey = keypair.publicKey, - toPublicKey = nonceAccount.publicKey, - lamports = 1_000_000_000, - ) - ) - .setRecentBlockHash(nonce!!.nonce) - .build() - .sign(keypair) - - val testSignature = client.sendTransaction(testTransaction) - println("Advanced nonce account: $testSignature") - - delay(15.seconds) - - val testTxInfo = client.getTransaction(testSignature, Commitment.Confirmed) - println("Transaction info: ${testTxInfo?.decode()}") - - val newNonce = client.getNonce(nonceAccount.publicKey, Commitment.Processed) - println("New nonce account info: $newNonce") + private suspend fun SolanaClient.waitForTransaction( + vararg signatures: String, + commitment: Commitment = Commitment.Finalized, + ) = coroutineScope { + signatures.map { signature -> + async { + var transactionResponse: TransactionResponse? + do { + transactionResponse = getTransaction(signature, commitment) + } while (transactionResponse == null) + logger.info { "Transaction $commitment $signature" } + } + }.awaitAll() } } diff --git a/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/vendor/IsOnCurveTest.kt b/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/vendor/IsOnCurveTest.kt index fa83052..16f6fce 100644 --- a/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/vendor/IsOnCurveTest.kt +++ b/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/vendor/IsOnCurveTest.kt @@ -5,23 +5,11 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest import net.avianlabs.solana.domain.program.ProgramDerivedAddress import net.avianlabs.solana.domain.program.associatedTokenAddress -import net.avianlabs.solana.domain.randomKey import net.avianlabs.solana.tweetnacl.ed25519.PublicKey import kotlin.test.Test import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertTrue class IsOnCurveTest { - @Test - fun testIsOnCurve() { - val offCurve = PublicKey.fromBase58("12rqwuEgBYiGhBrDJStCiqEtzQpTTiZbh7teNVLuYcFA") - assertFalse(offCurve.isOnCurve()) - - val onCurve = randomKey().publicKey - assertTrue(onCurve.isOnCurve()) - } - @Test fun testParallelAssociatedAddress() = runTest { val x = PublicKey.fromBase58("4rZoSK72jVaAW1ayZLrefdMPAAStRVhCfH1PSundaoNt") diff --git a/solana-kotlin/src/commonTest/resources/simplelogger.properties b/solana-kotlin/src/commonTest/resources/simplelogger.properties new file mode 100644 index 0000000..fd1b252 --- /dev/null +++ b/solana-kotlin/src/commonTest/resources/simplelogger.properties @@ -0,0 +1,27 @@ +# SLF4J's SimpleLogger configuration file +# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err. +# Default logging detail level for all instances of SimpleLogger. +# Must be one of ("trace", "debug", "info", "warn", or "error"). +# If not specified, defaults to "info". +org.slf4j.simpleLogger.defaultLogLevel=debug +# Logging detail level for a SimpleLogger instance named "xxxxx". +# Must be one of ("trace", "debug", "info", "warn", or "error"). +# If not specified, the default logging detail level is used. +#org.slf4j.simpleLogger.log.xxxxx= +# Set to true if you want the current date and time to be included in output messages. +# Default is false, and will output the number of milliseconds elapsed since startup. +org.slf4j.simpleLogger.showDateTime=true +# The date and time format to be used in the output messages. +# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat. +# If the format is not specified or is invalid, the default format is used. +# The default format is yyyy-MM-dd HH:mm:ss:SSS Z. +org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z +# Set to true if you want to output the current thread name. +# Defaults to true. +org.slf4j.simpleLogger.showThreadName=false +# Set to true if you want the Logger instance name to be included in output messages. +# Defaults to true. +org.slf4j.simpleLogger.showLogName=false +# Set to true if you want the last component of the name to be included in output messages. +# Defaults to false. +#org.slf4j.simpleLogger.showShortLogName=false diff --git a/tweetnacl-multiplatform/build.gradle.kts b/tweetnacl-multiplatform/build.gradle.kts index fc49cbd..97bda55 100644 --- a/tweetnacl-multiplatform/build.gradle.kts +++ b/tweetnacl-multiplatform/build.gradle.kts @@ -1,4 +1,5 @@ import co.touchlab.cklib.gradle.CompileToBitcode.Language +import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget plugins { @@ -40,23 +41,54 @@ kotlin { mingwX64() linuxX64() + js(KotlinJsCompilerType.IR) { + browser { + compilations.all { + kotlinOptions { + sourceMap = true + sourceMapEmbedSources = "always" + } + } + testTask { + useMocha() + } + } + nodejs { + compilations.all { + kotlinOptions { + sourceMap = true + sourceMapEmbedSources = "always" + } + } + } + generateTypeScriptDefinitions() + useEsModules() + } + sourceSets { val jvmMain by getting { dependencies { implementation(libs.tweetNaClJava) implementation(libs.bouncyCastle) + implementation(libs.slf4j.api) + } + } + val jvmTest by getting { + dependencies { + implementation(libs.slf4j.simple) } } - val jvmTest by getting val commonMain by getting { dependencies { + implementation(libs.kotlinLogging) } } val commonTest by getting { dependencies { implementation(libs.kotlinTest) implementation(libs.coroutinesTest) + implementation(libs.ktorUtils) } } @@ -70,6 +102,13 @@ kotlin { val nativeMain by getting { } + val jsMain by getting { + dependencies { + implementation(npm("tweetnacl", "1.0.3")) + implementation(npm("@noble/curves", "1.4.0")) + } + } + targets.withType { val main by compilations.getting diff --git a/tweetnacl-multiplatform/src/commonTest/kotlin/net/avianlabs/solana/vendor/IsOnCurveTest.kt b/tweetnacl-multiplatform/src/commonTest/kotlin/net/avianlabs/solana/vendor/IsOnCurveTest.kt new file mode 100644 index 0000000..7016157 --- /dev/null +++ b/tweetnacl-multiplatform/src/commonTest/kotlin/net/avianlabs/solana/vendor/IsOnCurveTest.kt @@ -0,0 +1,19 @@ +package net.avianlabs.solana.tweetnacl.net.avianlabs.solana.vendor + +import net.avianlabs.solana.tweetnacl.TweetNaCl +import net.avianlabs.solana.tweetnacl.ed25519.PublicKey +import kotlin.random.Random +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class IsOnCurveTest { + @Test + fun testIsOnCurve() { + val offCurve = PublicKey.fromBase58("12rqwuEgBYiGhBrDJStCiqEtzQpTTiZbh7teNVLuYcFA") + assertFalse(offCurve.isOnCurve()) + + val onCurve = TweetNaCl.Signature.generateKey(Random.nextBytes(32)).publicKey + assertTrue(onCurve.isOnCurve()) + } +} diff --git a/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/vendor/Sha256Test.kt b/tweetnacl-multiplatform/src/commonTest/kotlin/net/avianlabs/solana/vendor/Sha256Test.kt similarity index 92% rename from solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/vendor/Sha256Test.kt rename to tweetnacl-multiplatform/src/commonTest/kotlin/net/avianlabs/solana/vendor/Sha256Test.kt index f44efcc..0ad16ad 100644 --- a/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/vendor/Sha256Test.kt +++ b/tweetnacl-multiplatform/src/commonTest/kotlin/net/avianlabs/solana/vendor/Sha256Test.kt @@ -1,4 +1,4 @@ -package net.avianlabs.solana.vendor +package net.avianlabs.solana.tweetnacl.net.avianlabs.solana.vendor import io.ktor.util.* import kotlinx.coroutines.Dispatchers diff --git a/tweetnacl-multiplatform/src/jsMain/kotlin/net/avianlabs/solana/tweetnacl/Curves.kt b/tweetnacl-multiplatform/src/jsMain/kotlin/net/avianlabs/solana/tweetnacl/Curves.kt new file mode 100644 index 0000000..6a5b453 --- /dev/null +++ b/tweetnacl-multiplatform/src/jsMain/kotlin/net/avianlabs/solana/tweetnacl/Curves.kt @@ -0,0 +1,17 @@ +package net.avianlabs.solana.tweetnacl + +import org.khronos.webgl.Uint8Array + +@JsModule("@noble/curves/ed25519") +internal external object Curves { + val ed25519: Ed25519 +} + +internal external interface Ed25519 { + @JsName("ExtendedPoint") + val extendedPoint: ExtendedPoint +} + +internal external interface ExtendedPoint { + fun fromHex(publicKey: Uint8Array): dynamic +} diff --git a/tweetnacl-multiplatform/src/jsMain/kotlin/net/avianlabs/solana/tweetnacl/TweetNaCl.kt b/tweetnacl-multiplatform/src/jsMain/kotlin/net/avianlabs/solana/tweetnacl/TweetNaCl.kt new file mode 100644 index 0000000..f9dc620 --- /dev/null +++ b/tweetnacl-multiplatform/src/jsMain/kotlin/net/avianlabs/solana/tweetnacl/TweetNaCl.kt @@ -0,0 +1,44 @@ +package net.avianlabs.solana.tweetnacl + +import net.avianlabs.solana.tweetnacl.ed25519.Ed25519Keypair +import org.khronos.webgl.Uint8Array +import org.khronos.webgl.get + +internal actual fun signInternal(message: ByteArray, secretKey: ByteArray): ByteArray = + tweetNaclJs.sign.detached(message.asUint8Array(), secretKey.asUint8Array()).asByteArray() + +internal actual fun isOnCurveInternal(publicKey: ByteArray): Boolean = + try { + Curves.ed25519.extendedPoint.fromHex(publicKey.asUint8Array()) + true + } catch (e: Throwable) { + false + } + +internal actual fun generateKeyInternal(seed: ByteArray): Ed25519Keypair { + val bytes = tweetNaclJs.sign.keyPair.fromSeed(seed.asUint8Array()) + return Ed25519Keypair.fromSecretKeyBytes(bytes.secretKey.asByteArray()) +} + +internal actual fun secretBoxInternal(secretKey: ByteArray): TweetNaCl.SecretBox = + object : TweetNaCl.SecretBox { + override fun box(message: ByteArray, nonce: ByteArray): ByteArray { + return tweetNaclJs.secretbox( + message.asUint8Array(), + nonce.asUint8Array(), + secretKey.asUint8Array() + ).asByteArray() + } + + override fun open(box: ByteArray, nonce: ByteArray): ByteArray { + return tweetNaclJs.secretbox.open( + box.asUint8Array(), + nonce.asUint8Array(), + secretKey.asUint8Array() + ).asByteArray() + } + } + +private fun ByteArray.asUint8Array(): Uint8Array = Uint8Array(this.toTypedArray()) + +private fun Uint8Array.asByteArray(): ByteArray = ByteArray(this.length) { this[it] } diff --git a/tweetnacl-multiplatform/src/jsMain/kotlin/net/avianlabs/solana/tweetnacl/TweetNaClJs.kt b/tweetnacl-multiplatform/src/jsMain/kotlin/net/avianlabs/solana/tweetnacl/TweetNaClJs.kt new file mode 100644 index 0000000..5adc99a --- /dev/null +++ b/tweetnacl-multiplatform/src/jsMain/kotlin/net/avianlabs/solana/tweetnacl/TweetNaClJs.kt @@ -0,0 +1,37 @@ +package net.avianlabs.solana.tweetnacl + +import org.khronos.webgl.Uint8Array + +@JsModule("tweetnacl") +internal external val tweetNaclJs: TweetNaClJs + +internal external interface TweetNaClJs { + val secretbox: SecretBox + val sign: Sign +} + +internal external interface Sign { + fun detached(message: Uint8Array, secretKey: Uint8Array): Uint8Array + val keyPair: KeyPair +} + +internal external interface KeyPair { + fun fromSeed(seed: Uint8Array): SignKeyPair +} + +internal external interface SignKeyPair { + val secretKey: Uint8Array + val publicKey: Uint8Array +} + +internal external interface SecretBox { + fun open(box: Uint8Array, nonce: Uint8Array, secretKey: Uint8Array): Uint8Array +} + + +@Suppress("NOTHING_TO_INLINE") +internal inline operator fun SecretBox.invoke( + message: Uint8Array, + nonce: Uint8Array, + secretKey: Uint8Array +): Uint8Array = asDynamic()(message, nonce, secretKey) as Uint8Array