From 68ddb56585ef6c9acaeb66dfb06cb6f73dd0fcb4 Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Mon, 1 Aug 2022 10:31:05 -0400 Subject: [PATCH 01/36] Add types & detection for keplr functionality, fix Transfer test --- packages/anoma-wallet/package.json | 3 +- packages/anoma-wallet/src/lib/Keplr.ts | 30 ++ packages/anoma-wallet/src/lib/index.ts | 9 +- .../anoma-wallet/src/lib/tx/Transfer.test.ts | 2 +- yarn.lock | 412 +++++++++++++++++- 5 files changed, 441 insertions(+), 15 deletions(-) create mode 100644 packages/anoma-wallet/src/lib/Keplr.ts diff --git a/packages/anoma-wallet/package.json b/packages/anoma-wallet/package.json index 2c5d1198b46..b799faf2da2 100644 --- a/packages/anoma-wallet/package.json +++ b/packages/anoma-wallet/package.json @@ -72,6 +72,7 @@ }, "devDependencies": { "@craco/craco": "^6.4.3", + "@keplr-wallet/types": "^0.10.13", "@playwright/test": "^1.24.1", "@testing-library/jest-dom": "^5.16.2", "@testing-library/react": "^12.1.3", @@ -99,4 +100,4 @@ "prettier": "^2.5.1", "ts-loader": "^9.2.7" } -} \ No newline at end of file +} diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts new file mode 100644 index 00000000000..8cebea55ea4 --- /dev/null +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -0,0 +1,30 @@ +import { ChainInfo } from "@keplr-wallet/types"; +import { Chain } from "config"; + +type SuggestChain = (chainInfo: ChainInfo) => Promise; + +type WindowWithKeplr = Window & + typeof globalThis & { + keplr: { + experimentalSuggestChain?: SuggestChain; + }; + }; + +class Keplr { + private _suggestChain: SuggestChain | undefined; + + constructor(private _chain: Chain) { + const keplr = (window)?.keplr; + this._suggestChain = keplr?.experimentalSuggestChain; + } + + public get chain(): Chain { + return this._chain; + } + + public detect(): boolean { + return !!this._suggestChain; + } +} + +export default Keplr; diff --git a/packages/anoma-wallet/src/lib/index.ts b/packages/anoma-wallet/src/lib/index.ts index 6eb36dc0ca6..c59135cd230 100644 --- a/packages/anoma-wallet/src/lib/index.ts +++ b/packages/anoma-wallet/src/lib/index.ts @@ -1,8 +1,9 @@ -export { default as RpcClient } from "lib/rpc/RpcClient"; -export { default as SocketClient } from "lib/rpc/SocketClient"; export { default as Account } from "lib/tx/Account"; -export { default as Transfer } from "lib/tx/Transfer"; export { default as IBCTransfer } from "lib/tx/IBCTransfer"; +export { default as Keplr } from "lib/Keplr"; export { default as Keypair } from "lib/Keypair"; -export { default as Wallet } from "lib/Wallet"; +export { default as RpcClient } from "lib/rpc/RpcClient"; export { default as Session } from "lib/Session"; +export { default as SocketClient } from "lib/rpc/SocketClient"; +export { default as Transfer } from "lib/tx/Transfer"; +export { default as Wallet } from "lib/Wallet"; diff --git a/packages/anoma-wallet/src/lib/tx/Transfer.test.ts b/packages/anoma-wallet/src/lib/tx/Transfer.test.ts index a430bb046b3..cd55d4497e5 100644 --- a/packages/anoma-wallet/src/lib/tx/Transfer.test.ts +++ b/packages/anoma-wallet/src/lib/tx/Transfer.test.ts @@ -38,6 +38,6 @@ describe("Transfer wasm and class methods", () => { }); expect(hash.length).toBe(64); - expect(bytes.length).toBe(596); + expect(bytes.length).toBe(597); }); }); diff --git a/yarn.lock b/yarn.lock index e3a99405a09..16ac43801d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1092,6 +1092,24 @@ ripemd160 "^2.0.2" sha.js "^2.4.11" +"@cosmjs/crypto@^0.24.1": + version "0.24.1" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.24.1.tgz#62da59c32b26344f26b10dd31a02b93655586d04" + integrity sha512-GPhaWmQO06mXldKj/b+oKF5o3jMNfRKpAw+Q8XQhrD7ItinVPDMu8Xgl6frUXWTUdgpYwqpvqOcpm85QUsYV0Q== + dependencies: + "@cosmjs/encoding" "^0.24.1" + "@cosmjs/math" "^0.24.1" + "@cosmjs/utils" "^0.24.1" + bip39 "^3.0.2" + bn.js "^4.11.8" + elliptic "^6.5.3" + js-sha3 "^0.8.0" + libsodium-wrappers "^0.7.6" + pbkdf2 "^3.1.1" + ripemd160 "^2.0.2" + sha.js "^2.4.11" + unorm "^1.5.0" + "@cosmjs/encoding@0.27.1", "@cosmjs/encoding@^0.27.1": version "0.27.1" resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.27.1.tgz#3cd5bc0af743485eb2578cdb08cfa84c86d610e1" @@ -1101,6 +1119,24 @@ bech32 "^1.1.4" readonly-date "^1.0.0" +"@cosmjs/encoding@^0.20.0": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.20.1.tgz#1d1162b3eca51b7244cd45102e313612cea77281" + integrity sha512-aBp153iq2LD4GwDGwodDWZk/eyAUZ8J8bbiqZ1uK8rrylzm9Rdw84aa6JxykezJe+uBPtoI4lx9eH7VQXCGDXw== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + +"@cosmjs/encoding@^0.24.1": + version "0.24.1" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.24.1.tgz#b30e92cdb70fc200a163b8c7aa5254606c8a09ab" + integrity sha512-PMr+gaXAuM0XgjeXwB1zdX1QI0t+PgVhbmjgI/RSgswDzdExNH97qUopecL0/HG3p64vhIT/6ZjXYYTljZL7WA== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + "@cosmjs/json-rpc@0.27.1", "@cosmjs/json-rpc@^0.27.1": version "0.27.1" resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.27.1.tgz#ce0a6157f57a76e964587ceb9027884bc4ffe701" @@ -1109,6 +1145,18 @@ "@cosmjs/stream" "0.27.1" xstream "^11.14.0" +"@cosmjs/launchpad@^0.24.0-alpha.25", "@cosmjs/launchpad@^0.24.1": + version "0.24.1" + resolved "https://registry.yarnpkg.com/@cosmjs/launchpad/-/launchpad-0.24.1.tgz#fe7e80734dfd60ea093429a646d7a38634c70134" + integrity sha512-syqVGKRH6z1vw4DdAJOSu4OgUXJdkXQozqvDde0cXYwnvhb7EXGSg5CTtp+2GqTBJuNVfMZ2DSvrC2Ig8cWBQQ== + dependencies: + "@cosmjs/crypto" "^0.24.1" + "@cosmjs/encoding" "^0.24.1" + "@cosmjs/math" "^0.24.1" + "@cosmjs/utils" "^0.24.1" + axios "^0.21.1" + fast-deep-equal "^3.1.3" + "@cosmjs/math@0.27.1": version "0.27.1" resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.27.1.tgz#be78857b008ffc6b1ed6fecaa1c4cd5bc38c07d7" @@ -1116,6 +1164,29 @@ dependencies: bn.js "^5.2.0" +"@cosmjs/math@^0.20.0": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.20.1.tgz#c3c2be821b8b5dbbb9b2c0401bd9f1472e821f2a" + integrity sha512-xt7BmpSw2OVGM2+JhlJvKv9OJs9+3DqgVL6+byUDC355CSISrZhFjJg9GFko1EFssDXz5YgvBZR5FkifC0xazw== + dependencies: + bn.js "^4.11.8" + +"@cosmjs/math@^0.24.1": + version "0.24.1" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.24.1.tgz#9eed507885aacc9b269441fc9ecb00fb5876883a" + integrity sha512-eBQk8twgzmpHFCVkoNjTZhsZwWRbR+JXt0FhjXJoD85SBm4K8b2OnOyTg68uPHVKOJjLRwzyRVYgMrg5TBVgwQ== + dependencies: + bn.js "^4.11.8" + +"@cosmjs/proto-signing@^0.24.0-alpha.25": + version "0.24.1" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.24.1.tgz#4ee38d4e0d29c626344fb832235fda8e8d645c28" + integrity sha512-/rnyNx+FlG6b6O+igsb42eMN1/RXY+pTrNnAE8/YZaRloP9A6MXiTMO5JdYSTcjaD0mEVhejiy96bcyflKYXBg== + dependencies: + "@cosmjs/launchpad" "^0.24.1" + long "^4.0.0" + protobufjs "~6.10.2" + "@cosmjs/socket@0.27.1": version "0.27.1" resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.27.1.tgz#c7a3eceb15efb9874a048c3238d1f0b185185742" @@ -1153,6 +1224,16 @@ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.27.1.tgz#1c8efde17256346ef142a3bd15158ee4055470e2" integrity sha512-VG7QPDiMUzVPxRdJahDV8PXxVdnuAHiIuG56hldV4yPnOz/si/DLNd7VAUUA5923b6jS1Hhev0Hr6AhEkcxBMg== +"@cosmjs/utils@^0.20.0": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.20.1.tgz#4d239b7d93c15523cdf109f225cbf61326fb69cd" + integrity sha512-xl9YnIrAAaBd6nFffwFbyrnKjqjD9zKGP8OBKxzyglxamHfqAS+PcJPEiaEpt+oUt7HAIOyhL3KK75Dh52hGvA== + +"@cosmjs/utils@^0.24.1": + version "0.24.1" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.24.1.tgz#0adfefe63b7f17222bc2bc12f71296f35e7ad378" + integrity sha512-VA3WFx1lMFb7esp9BqHWkDgMvHoA3D9w+uDRvWhVRpUpDc7RYHxMbWExASjz+gNblTCg556WJGzF64tXnf9tdQ== + "@craco/craco@^6.4.3": version "6.4.3" resolved "https://registry.yarnpkg.com/@craco/craco/-/craco-6.4.3.tgz#784395b6ebab764056550a2860494d24c3abd44e" @@ -1297,6 +1378,48 @@ resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== +"@iov/crypto@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@iov/crypto/-/crypto-2.1.0.tgz#10e91b6692e154958c11626dfd096a80e8a481a4" + integrity sha512-jnb4XuK50admolm7fBxOcxfAW2TO+wYrZlhDWiMETItY/Y5gNNa1zaDSO2wNIjjfGng+8nQ1yqnNhqy7busV2Q== + dependencies: + "@iov/encoding" "^2.1.0" + bip39 "^3.0.2" + bn.js "^4.11.8" + elliptic "^6.4.0" + js-sha3 "^0.8.0" + libsodium-wrappers "^0.7.6" + pbkdf2 "^3.0.16" + ripemd160 "^2.0.2" + sha.js "^2.4.11" + type-tagger "^1.0.0" + unorm "^1.5.0" + +"@iov/encoding@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@iov/encoding/-/encoding-2.1.0.tgz#434203c39874c68bc1d96e1278251f0feb23be07" + integrity sha512-5IOdLO7Xg/uRykuiCqeMYghQ3IjWDtGxv7NTWXkgpHuna0aewx43mRpT2NPCpOZd1tpuorDtQ7/zbDNRaIIF/w== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.3" + bn.js "^4.11.8" + readonly-date "^1.0.0" + +"@iov/encoding@^2.1.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@iov/encoding/-/encoding-2.5.0.tgz#9612e529f45e63633b2375c13db28b9330ce6293" + integrity sha512-HGHLlQEvD23rFjW5PQrxD2B/6LiBHVSxqX6gjOz9KfcmIMIftRA0qROrTITfjjjUr/yZZEeNk4qjuBls9TaYcA== + dependencies: + "@cosmjs/encoding" "^0.20.0" + "@cosmjs/math" "^0.20.0" + "@cosmjs/utils" "^0.20.0" + readonly-date "^1.0.0" + +"@iov/utils@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@iov/utils/-/utils-2.0.2.tgz#3527f376d26100e07ac823bf87bebd0f24680d1c" + integrity sha512-4D8MEvTcFc/DVy5q25vHxRItmgJyeX85dixMH+MxdKr+yy71h3sYk+sVBEIn70uqGP7VqAJkGOPNFs08/XYELw== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -1500,6 +1623,17 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@keplr-wallet/types@^0.10.13": + version "0.10.13" + resolved "https://registry.yarnpkg.com/@keplr-wallet/types/-/types-0.10.13.tgz#1c2e64cdcd0ef51e5168375b77a739366c406034" + integrity sha512-15dLe1oGQjY1nLGQeJERrKawMqPcU6QAY+9eglI2TNi6KGpmpH1PsDb+UIQNCehBTvYfKQl+vdFwHh3Eyw5VWA== + dependencies: + "@cosmjs/launchpad" "^0.24.0-alpha.25" + "@cosmjs/proto-signing" "^0.24.0-alpha.25" + axios "^0.21.4" + long "^4.0.0" + secretjs "^0.17.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1544,6 +1678,59 @@ schema-utils "^3.0.0" source-map "^0.7.3" +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + "@reduxjs/toolkit@^1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.8.0.tgz#8ae875e481ed97e4a691aafa034f876bfd0413c4" @@ -1995,6 +2182,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + "@types/luxon@^2.3.1": version "2.3.1" resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-2.3.1.tgz#e34763178b46232e4c5f079f1706e18692415519" @@ -2015,6 +2207,16 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== +"@types/node@>=13.7.0": + version "18.6.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.3.tgz#4e4a95b6fe44014563ceb514b2598b3e623d1c98" + integrity sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg== + +"@types/node@^13.7.0": + version "13.13.52" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7" + integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== + "@types/node@^16.11.25": version "16.11.26" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.26.tgz#63d204d136c9916fb4dcd1b50f9740fe86884e47" @@ -2734,7 +2936,14 @@ axe-core@^4.3.5: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.1.tgz#7dbdc25989298f9ad006645cd396782443757413" integrity sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw== -axios@^0.21.2: +axios@0.21.1: + version "0.21.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" + integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== + dependencies: + follow-redirects "^1.10.0" + +axios@^0.21.1, axios@^0.21.2, axios@^0.21.4: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== @@ -2931,7 +3140,7 @@ base-x@^4.0.0: resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== -base64-js@^1.3.0, base64-js@^1.3.1: +base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -2941,7 +3150,7 @@ batch@0.6.1: resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= -bech32@^1.1.4: +bech32@^1.1.3, bech32@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== @@ -2981,7 +3190,7 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.11.9: +bn.js@^4.11.8, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== @@ -3107,7 +3316,7 @@ buffer-indexof@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== -buffer@^6.0.3: +buffer@6.0.3, buffer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== @@ -3115,6 +3324,14 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" +buffer@~5.4.3: + version "5.4.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" + integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + builtin-modules@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" @@ -3247,6 +3464,11 @@ chardet@^0.4.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= +charenc@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== + check-types@^11.1.1: version "11.1.2" resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.1.2.tgz#86a7c12bf5539f6324eb0e70ca8896c0e38f3e2f" @@ -3599,6 +3821,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +crypt@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== + crypto-js@3.1.9-1: version "3.1.9-1" resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.9-1.tgz#fda19e761fc077e01ffbfdc6e9fdfc59e8806cd8" @@ -3839,6 +4066,11 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33" integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw== +curve25519-js@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/curve25519-js/-/curve25519-js-0.0.4.tgz#e6ad967e8cd284590d657bbfc90d8b50e49ba060" + integrity sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w== + damerau-levenshtein@^1.0.7: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" @@ -4180,7 +4412,7 @@ electron-to-chromium@^1.4.84: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.86.tgz#90fe4a9787f48d6522957213408e08a8126b2ebc" integrity sha512-EVTZ+igi8x63pK4bPuA95PXIs2b2Cowi3WQwI9f9qManLiZJOD1Lash1J3W4TvvcUCcIR4o/rgi9o8UicXSO+w== -elliptic@^6.5.3: +elliptic@^6.4.0, elliptic@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -4724,6 +4956,11 @@ external-editor@^2.0.4: iconv-lite "^0.4.17" tmp "^0.0.33" +fast-deep-equal@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -4887,6 +5124,11 @@ follow-redirects@^1.0.0, follow-redirects@^1.14.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== +follow-redirects@^1.10.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.0" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.0.tgz#0282b335fa495a97e167f69018f566ea7d2a2b5e" @@ -5213,7 +5455,7 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" -hash.js@^1.0.0, hash.js@^1.0.3: +hash.js@^1.0.0, hash.js@^1.0.3, hash.js@~1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== @@ -5431,7 +5673,7 @@ identity-obj-proxy@^3.0.0: dependencies: harmony-reflect "^1.4.6" -ieee754@^1.2.1: +ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -5574,6 +5816,11 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-buffer@~1.1.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" @@ -6250,6 +6497,52 @@ jest@^27.4.3, jest@^27.5.1: import-local "^3.0.2" jest-cli "^27.5.1" +js-crypto-env@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/js-crypto-env/-/js-crypto-env-0.3.2.tgz#02195723469da14449338ca2789fd7ff6784c533" + integrity sha512-F1uHiCkSOo36qBuuZABA4sBf+xeFBzhJZ0Sd7af8FAruszIhm1Xxv+Zr5Ne90Zlh7/fnxCsrdkj0N8f0a3lVlQ== + +js-crypto-hash@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/js-crypto-hash/-/js-crypto-hash-0.6.3.tgz#748e3e1853f69dad714636db3290736825506641" + integrity sha512-SG8c9tM8y3sUb4k7WvpVfu5vU7zfPvX+eaYR5578TvehkehdaQbqAc+y+1FwxnqQ3WZ0gsYoOKp/mW+mqtNoWA== + dependencies: + buffer "~5.4.3" + hash.js "~1.1.7" + js-crypto-env "^0.3.2" + md5 "~2.2.1" + sha3 "~2.1.0" + +js-crypto-hkdf@0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/js-crypto-hkdf/-/js-crypto-hkdf-0.7.3.tgz#537c394a2e65bca80032daa07d2ffe7e4f78d32f" + integrity sha512-eAaVArAjS2GCacWGXY4hjBiexrLQYlI0PMOcbwtrSEj84XU3kUfMYZm9bpTyaTXgdHC/eQoXe/Of6biG+RSEaQ== + dependencies: + js-crypto-env "^0.3.2" + js-crypto-hmac "^0.6.3" + js-crypto-random "^0.4.3" + js-encoding-utils "0.5.6" + +js-crypto-hmac@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/js-crypto-hmac/-/js-crypto-hmac-0.6.3.tgz#c33352c1ee6076b17b8f4cb0e2167814b2b77d6d" + integrity sha512-T0pKOaHACOSG6Xs6/06G8RDDeZouQwIQNBq9L/zoUGsd4F67gAjpT3q2lGigAGpUd1hiyy7vnhvLpz7VDt6DbA== + dependencies: + js-crypto-env "^0.3.2" + js-crypto-hash "^0.6.3" + +js-crypto-random@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/js-crypto-random/-/js-crypto-random-0.4.3.tgz#898c2d91991eead02b4e461005e878fa9827fd74" + integrity sha512-C3gzphPPfw9jfQ9Q/LjhJMZxQNp3AaoVRDvyZkiB+zYltfs8tKQPsskWkXACpg1Nzh01PtSRUvVijjptd2qGHQ== + dependencies: + js-crypto-env "^0.3.2" + +js-encoding-utils@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/js-encoding-utils/-/js-encoding-utils-0.5.6.tgz#517351d8f4a85b2ad121183d41df8319981bee03" + integrity sha512-qnAGsUIWrmzh5n+3AXqbxX1KsB9hkQmJZf3aA9DLAS7GpL/NEHCBreFFbW+imramoU+Q0TDyvkwhRbBRH1TVkg== + js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -6567,6 +6860,11 @@ lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -6641,6 +6939,15 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +md5@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + integrity sha512-PlGG4z5mBANDGCKsYQe0CaUYHdZYZt8ZPZLmEt+Urf0W4GlpTX4HescwHU+dc9+Z/G/vZKYZYFrwgm9VxK6QOQ== + dependencies: + charenc "~0.0.1" + crypt "~0.0.1" + is-buffer "~1.1.1" + mdn-data@2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" @@ -6766,6 +7073,11 @@ minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +miscreant@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/miscreant/-/miscreant-0.3.2.tgz#a91c046566cca70bd6b5e9fbdd3f67617fa85034" + integrity sha512-fL9KxsQz9BJB2KGPMHFrReioywkiomBiuaLk6EuChijK0BsJsIKJXdVomR+/bPj5mvbFD6wM0CM3bZio9g7OHA== + mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -7150,6 +7462,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +pako@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + param-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" @@ -7241,7 +7558,7 @@ path@^0.12.7: process "^0.11.1" util "^0.10.3" -pbkdf2@^3.0.9: +pbkdf2@^3.0.16, pbkdf2@^3.0.9, pbkdf2@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== @@ -7919,6 +8236,44 @@ prop-types@^15.5.8, prop-types@^15.7.2, prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" +protobufjs@^6.11.2: + version "6.11.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" + integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + +protobufjs@~6.10.2: + version "6.10.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.3.tgz#11ed1dd02acbfcb330becf1611461d4b407f9eef" + integrity sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" "^13.7.0" + long "^4.0.0" + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -8622,6 +8977,28 @@ sdp@^2.6.0, sdp@^2.9.0: resolved "https://registry.yarnpkg.com/sdp/-/sdp-2.12.0.tgz#338a106af7560c86e4523f858349680350d53b22" integrity sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw== +secretjs@^0.17.0: + version "0.17.5" + resolved "https://registry.yarnpkg.com/secretjs/-/secretjs-0.17.5.tgz#5b55e46cfa2719714831fc2019e21c21959fe587" + integrity sha512-sf0+Je9KIEMQr/wJOgeqyBOV0ruiMNHSwP4L2vXiJbtzJWQqyVHyPkpavAhruNZ+91XlSzAFP2X5MPxqPBC9fQ== + dependencies: + "@iov/crypto" "2.1.0" + "@iov/encoding" "2.1.0" + "@iov/utils" "2.0.2" + axios "0.21.1" + curve25519-js "0.0.4" + fast-deep-equal "3.1.1" + js-crypto-hkdf "0.7.3" + miscreant "0.3.2" + pako "1.0.11" + protobufjs "^6.11.2" + secure-random "1.1.2" + +secure-random@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/secure-random/-/secure-random-1.1.2.tgz#ed103b460a851632d420d46448b2a900a41e7f7c" + integrity sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ== + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -8730,6 +9107,13 @@ sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +sha3@~2.1.0: + version "2.1.4" + resolved "https://registry.yarnpkg.com/sha3/-/sha3-2.1.4.tgz#000fac0fe7c2feac1f48a25e7a31b52a6492cc8f" + integrity sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg== + dependencies: + buffer "6.0.3" + shallowequal@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" @@ -9516,6 +9900,11 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +type-tagger@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/type-tagger/-/type-tagger-1.0.0.tgz#dc6297e52e17097c1b92b42c16816a18f631e7f4" + integrity sha512-FIPqqpmDgdaulCnRoKv1/d3U4xVBUrYn42QXWNP3XYmgfPUDuBUsgFOb9ntT0aIe0UsUP+lknpQ5d9Kn36RssA== + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -9578,6 +9967,11 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== +unorm@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" + integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" From 2fc02cf45c6710a0181e04232e3c8655dc93340a Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Tue, 2 Aug 2022 05:51:42 -0400 Subject: [PATCH 02/36] Construct ChainInfo config, invoke experimentalSuggestChain --- packages/anoma-wallet/src/lib/Keplr.ts | 54 ++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index 8cebea55ea4..8d3a6f263a8 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -1,5 +1,7 @@ import { ChainInfo } from "@keplr-wallet/types"; + import { Chain } from "config"; +import { Tokens, TokenType } from "constants/"; type SuggestChain = (chainInfo: ChainInfo) => Promise; @@ -25,6 +27,58 @@ class Keplr { public detect(): boolean { return !!this._suggestChain; } + + public async suggestChain(): Promise { + if (this._suggestChain) { + const { id, alias, network } = this._chain; + const { protocol, url, port } = network; + const rpcUrl = `${protocol}://${url}${port ? ":" + port : ""}`; + // The following should match our Rest API URL and be added to chain config + // instead of hard-coding port here: + const restUrl = `${protocol}://${url}:1317`; + + const tokenType: TokenType = "ATOM"; + const token = Tokens[tokenType]; + const { symbol, coinGeckoId } = token; + + const currency = { + coinDenom: symbol, + coinMinimalDenom: "uatom", // Add this to Token config? + coinDecimals: 6, + coinGeckoId, + }; + + const chainInfo: ChainInfo = { + rpc: rpcUrl, + rest: restUrl, + chainId: id, + chainName: alias, + stakeCurrency: currency, + bip44: { + coinType: token.type, + }, + bech32Config: { + bech32PrefixAccAddr: "cosmos", + // Should the following change to match Namada (e.g., "atest", etc)? + bech32PrefixAccPub: "cosmos" + "pub", + bech32PrefixValAddr: "cosmos" + "valoper", + bech32PrefixValPub: "cosmos" + "valoperpub", + bech32PrefixConsAddr: "cosmos" + "valcons", + bech32PrefixConsPub: "cosmos" + "valconspub", + }, + currencies: [currency], + feeCurrencies: [currency], + gasPriceStep: { low: 0.01, average: 0.025, high: 0.03 }, // This is optional! + }; + + console.log({ chainInfo }); + + await this._suggestChain(chainInfo); + + return true; + } + return false; + } } export default Keplr; From a289fe5f3ca8f39eeeb11cbac0568d0c6eb2b94b Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Tue, 2 Aug 2022 06:43:43 -0400 Subject: [PATCH 03/36] Correctly invoke suggest chain functionality --- .../SettingsWalletSettings.tsx | 25 +++++++++++++++- packages/anoma-wallet/src/lib/Keplr.ts | 30 +++++++++---------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx index ba17a5673fd..7dbc1da6155 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx @@ -4,7 +4,7 @@ import { useNavigate } from "react-router-dom"; import { Chain } from "config/chain"; import { setFiatCurrency, setChainId, SettingsState } from "slices/settings"; import { useAppDispatch, useAppSelector } from "store"; -import { Session } from "lib"; +import { Keplr, Session } from "lib"; import { Currencies } from "constants/"; import { NavigationContainer } from "components/NavigationContainer"; @@ -35,6 +35,10 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { const chains = Object.values(Config.chain); const { chainId } = useAppSelector((state) => state.settings); + const chain = Config.chain[chainId]; + + const keplr = new Keplr(chain); + const [displaySeedPhrase, setDisplaySeedPhrase] = useState(false); const [seedPhrase, setSeedPhrase] = useState([]); const [isLoadingSeed, setIsLoadingSeed] = useState(false); @@ -81,6 +85,15 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { dispatch(setChainId(value)); }; + const handleKeplrClick = (): void => { + if (keplr.detect()) { + (async () => { + const results = await keplr.suggestChain(); + console.log({ results }); + })(); + } + }; + return ( @@ -146,6 +159,16 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { onChange={handleNetworkSelect} /> + + {keplr.detect() && ( + + )} window)?.keplr; - this._suggestChain = keplr?.experimentalSuggestChain; - } + constructor( + private _chain: Chain, + private _keplr = (window)?.keplr + ) {} public get chain(): Chain { return this._chain; } public detect(): boolean { - return !!this._suggestChain; + return !!this._keplr?.experimentalSuggestChain; } public async suggestChain(): Promise { - if (this._suggestChain) { - const { id, alias, network } = this._chain; + if (this._keplr && this._keplr.experimentalSuggestChain) { + console.log(this._chain); + const { id: chainId, alias: chainName, network } = this._chain; const { protocol, url, port } = network; const rpcUrl = `${protocol}://${url}${port ? ":" + port : ""}`; // The following should match our Rest API URL and be added to chain config @@ -51,8 +50,8 @@ class Keplr { const chainInfo: ChainInfo = { rpc: rpcUrl, rest: restUrl, - chainId: id, - chainName: alias, + chainId, + chainName, stakeCurrency: currency, bip44: { coinType: token.type, @@ -73,11 +72,12 @@ class Keplr { console.log({ chainInfo }); - await this._suggestChain(chainInfo); - - return true; + return this._keplr + .experimentalSuggestChain(chainInfo) + .then(() => Promise.resolve(true)) + .catch(() => Promise.reject(false)); } - return false; + return Promise.reject(false); } } From 39fa94b755f9e32ccd3bd3c9b20616efd4166768 Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Tue, 2 Aug 2022 06:53:04 -0400 Subject: [PATCH 04/36] Additional functions for Keplr to detect chain --- packages/anoma-wallet/src/lib/Keplr.ts | 37 +++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index 8f557b2c044..e913ae06989 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -3,12 +3,19 @@ import { ChainInfo } from "@keplr-wallet/types"; import { Chain } from "config"; import { Tokens, TokenType } from "constants/"; -type SuggestChain = (chainInfo: ChainInfo) => Promise; - type WindowWithKeplr = Window & typeof globalThis & { keplr: { - experimentalSuggestChain?: SuggestChain; + experimentalSuggestChain?: (chainInfo: ChainInfo) => Promise; + enable: (chainId: string) => Promise; + getKey: (chainId: string) => Promise<{ + // Name of the selected key store. + name: string; + algo: string; + pubKey: Uint8Array; + address: Uint8Array; + bech32Address: string; + }>; }; }; @@ -79,6 +86,30 @@ class Keplr { } return Promise.reject(false); } + + public async enable(): Promise { + if (this._keplr) { + const { id } = this._chain; + + return this._keplr + .enable(id) + .then(() => Promise.resolve(true)) + .catch(() => Promise.reject(false)); + } + return false; + } + + public async getKey(): Promise { + if (this._keplr) { + const { id } = this._chain; + + return this._keplr + .getKey(id) + .then(() => Promise.resolve(true)) + .catch(() => Promise.reject(false)); + } + return false; + } } export default Keplr; From dd1c3508a776b4d35ff9c4ee8f062e0c57b4353a Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Tue, 2 Aug 2022 08:00:35 -0400 Subject: [PATCH 05/36] Add check for env for determining bech32 prefix, add "enable" functionality --- .../SettingsWalletSettings.tsx | 44 +++++++-- packages/anoma-wallet/src/lib/Keplr.ts | 97 ++++++++++++------- 2 files changed, 97 insertions(+), 44 deletions(-) diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx index 7dbc1da6155..8685a0f94ca 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx @@ -42,6 +42,8 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { const [displaySeedPhrase, setDisplaySeedPhrase] = useState(false); const [seedPhrase, setSeedPhrase] = useState([]); const [isLoadingSeed, setIsLoadingSeed] = useState(false); + const [isKeplrAddingChain, setIsKeplrAddingChain] = useState(false); + const [isKeplrConnecting, setIsKeplrConnecting] = useState(false); const networks = Object.values(chains).map(({ id, alias }: Chain) => ({ label: alias, @@ -85,11 +87,22 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { dispatch(setChainId(value)); }; - const handleKeplrClick = (): void => { + const handleKeplrSuggestChainClick = (): void => { + setIsKeplrAddingChain(true); if (keplr.detect()) { (async () => { - const results = await keplr.suggestChain(); - console.log({ results }); + await keplr.suggestChain(); + setIsKeplrAddingChain(false); + })(); + } + }; + + const handleKeplrEnableClick = (): void => { + setIsKeplrConnecting(true); + if (keplr.detect()) { + (async () => { + await keplr.enable(); + setIsKeplrConnecting(false); })(); } }; @@ -161,13 +174,24 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { {keplr.detect() && ( - + <> + + + )} diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index e913ae06989..e7e20f9e0f1 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -3,6 +3,11 @@ import { ChainInfo } from "@keplr-wallet/types"; import { Chain } from "config"; import { Tokens, TokenType } from "constants/"; +const { REACT_APP_LOCAL, NODE_ENV } = process.env; + +const PREFIX = "namada"; +const PREFIX_TESTNET = "atest"; + type WindowWithKeplr = Window & typeof globalThis & { keplr: { @@ -20,28 +25,79 @@ type WindowWithKeplr = Window & }; class Keplr { + /** + * Pass a chain config into constructor to instantiate, and optionally + * override keplr instance for testing + * @param _chain + * @param _keplr + */ constructor( private _chain: Chain, private _keplr = (window)?.keplr ) {} + /** + * Chain accessor get method + * @returns {Chain} + */ public get chain(): Chain { return this._chain; } + /** + * Determine if keplr extension is loaded + * @returns {boolean} + */ public detect(): boolean { return !!this._keplr?.experimentalSuggestChain; } + /** + * Enable connection to Keplr for current chain + * @returns {Promise} + */ + public async enable(): Promise { + if (this._keplr) { + const { id } = this._chain; + + return this._keplr + .enable(id) + .then(() => Promise.resolve(true)) + .catch(() => Promise.reject(false)); + } + return false; + } + + /** + * Get key for current chain + * @returns {Promise { + if (this._keplr) { + const { id } = this._chain; + + return this._keplr + .getKey(id) + .then(() => Promise.resolve(true)) + .catch(() => Promise.reject(false)); + } + return false; + } + + /** + * Suggest a chain to Keplr extension + * @returns {Promise} + */ public async suggestChain(): Promise { if (this._keplr && this._keplr.experimentalSuggestChain) { - console.log(this._chain); const { id: chainId, alias: chainName, network } = this._chain; const { protocol, url, port } = network; const rpcUrl = `${protocol}://${url}${port ? ":" + port : ""}`; // The following should match our Rest API URL and be added to chain config // instead of hard-coding port here: const restUrl = `${protocol}://${url}:1317`; + const bech32Prefix = + REACT_APP_LOCAL || NODE_ENV === "development" ? PREFIX_TESTNET : PREFIX; const tokenType: TokenType = "ATOM"; const token = Tokens[tokenType]; @@ -64,21 +120,18 @@ class Keplr { coinType: token.type, }, bech32Config: { - bech32PrefixAccAddr: "cosmos", - // Should the following change to match Namada (e.g., "atest", etc)? - bech32PrefixAccPub: "cosmos" + "pub", - bech32PrefixValAddr: "cosmos" + "valoper", - bech32PrefixValPub: "cosmos" + "valoperpub", - bech32PrefixConsAddr: "cosmos" + "valcons", - bech32PrefixConsPub: "cosmos" + "valconspub", + bech32PrefixAccAddr: bech32Prefix, + bech32PrefixAccPub: bech32Prefix + "pub", + bech32PrefixValAddr: bech32Prefix + "valoper", + bech32PrefixValPub: bech32Prefix + "valoperpub", + bech32PrefixConsAddr: bech32Prefix + "valcons", + bech32PrefixConsPub: bech32Prefix + "valconspub", }, currencies: [currency], feeCurrencies: [currency], gasPriceStep: { low: 0.01, average: 0.025, high: 0.03 }, // This is optional! }; - console.log({ chainInfo }); - return this._keplr .experimentalSuggestChain(chainInfo) .then(() => Promise.resolve(true)) @@ -86,30 +139,6 @@ class Keplr { } return Promise.reject(false); } - - public async enable(): Promise { - if (this._keplr) { - const { id } = this._chain; - - return this._keplr - .enable(id) - .then(() => Promise.resolve(true)) - .catch(() => Promise.reject(false)); - } - return false; - } - - public async getKey(): Promise { - if (this._keplr) { - const { id } = this._chain; - - return this._keplr - .getKey(id) - .then(() => Promise.resolve(true)) - .catch(() => Promise.reject(false)); - } - return false; - } } export default Keplr; From 59093b4d4759a16fff93376b87ae68100bd42d7f Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Tue, 2 Aug 2022 08:09:17 -0400 Subject: [PATCH 06/36] Clean up Keplr lib --- packages/anoma-wallet/src/lib/Keplr.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index e7e20f9e0f1..1413e16c417 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -11,7 +11,7 @@ const PREFIX_TESTNET = "atest"; type WindowWithKeplr = Window & typeof globalThis & { keplr: { - experimentalSuggestChain?: (chainInfo: ChainInfo) => Promise; + experimentalSuggestChain: (chainInfo: ChainInfo) => Promise; enable: (chainId: string) => Promise; getKey: (chainId: string) => Promise<{ // Name of the selected key store. @@ -49,7 +49,7 @@ class Keplr { * @returns {boolean} */ public detect(): boolean { - return !!this._keplr?.experimentalSuggestChain; + return !!this._keplr; } /** @@ -62,10 +62,10 @@ class Keplr { return this._keplr .enable(id) - .then(() => Promise.resolve(true)) + .then(() => true) .catch(() => Promise.reject(false)); } - return false; + return Promise.reject(false); } /** @@ -78,10 +78,10 @@ class Keplr { return this._keplr .getKey(id) - .then(() => Promise.resolve(true)) + .then(() => true) .catch(() => Promise.reject(false)); } - return false; + return Promise.reject(false); } /** @@ -89,7 +89,7 @@ class Keplr { * @returns {Promise} */ public async suggestChain(): Promise { - if (this._keplr && this._keplr.experimentalSuggestChain) { + if (this._keplr) { const { id: chainId, alias: chainName, network } = this._chain; const { protocol, url, port } = network; const rpcUrl = `${protocol}://${url}${port ? ":" + port : ""}`; @@ -134,7 +134,7 @@ class Keplr { return this._keplr .experimentalSuggestChain(chainInfo) - .then(() => Promise.resolve(true)) + .then(() => true) .catch(() => Promise.reject(false)); } return Promise.reject(false); From b1c46da4bc917905e5677d9966b5e19919da039e Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Tue, 2 Aug 2022 08:15:51 -0400 Subject: [PATCH 07/36] Additional clean up, fix mobile menu button width --- .../SettingsWalletSettings.tsx | 16 ++++++---------- .../TopNavigation/topNavigation.components.ts | 4 ++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx index 8685a0f94ca..4d8caf15ca0 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx @@ -87,23 +87,19 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { dispatch(setChainId(value)); }; - const handleKeplrSuggestChainClick = (): void => { + const handleKeplrSuggestChainClick = async (): Promise => { setIsKeplrAddingChain(true); if (keplr.detect()) { - (async () => { - await keplr.suggestChain(); - setIsKeplrAddingChain(false); - })(); + await keplr.suggestChain(); + setIsKeplrAddingChain(false); } }; - const handleKeplrEnableClick = (): void => { + const handleKeplrEnableClick = async (): Promise => { setIsKeplrConnecting(true); if (keplr.detect()) { - (async () => { - await keplr.enable(); - setIsKeplrConnecting(false); - })(); + await keplr.enable(); + setIsKeplrConnecting(false); } }; diff --git a/packages/anoma-wallet/src/App/TopNavigation/topNavigation.components.ts b/packages/anoma-wallet/src/App/TopNavigation/topNavigation.components.ts index f046e81babd..ae8bf23407c 100644 --- a/packages/anoma-wallet/src/App/TopNavigation/topNavigation.components.ts +++ b/packages/anoma-wallet/src/App/TopNavigation/topNavigation.components.ts @@ -235,6 +235,10 @@ export const MobileMenuListItem = styled.li` border-bottom: 1px solid ${(props) => props.theme.colors.buttonBackground4}; color: ${(props) => props.theme.colors.headingColor}; + & button { + width: 100%; + } + & button > div { color: ${(props) => props.theme.colors.headingColor}; From 2e5943637b90e36b5e7e80b507f8d2b1dba38511 Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Tue, 2 Aug 2022 09:33:25 -0400 Subject: [PATCH 08/36] Set up basic tests for Keplr lib module --- .../SettingsWalletSettings.tsx | 1 - packages/anoma-wallet/src/lib/Keplr.test.ts | 69 +++++++++++++++++++ packages/anoma-wallet/src/lib/Keplr.ts | 26 +++---- 3 files changed, 83 insertions(+), 13 deletions(-) create mode 100644 packages/anoma-wallet/src/lib/Keplr.test.ts diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx index 4d8caf15ca0..d91fb077043 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx @@ -36,7 +36,6 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { const chains = Object.values(Config.chain); const { chainId } = useAppSelector((state) => state.settings); const chain = Config.chain[chainId]; - const keplr = new Keplr(chain); const [displaySeedPhrase, setDisplaySeedPhrase] = useState(false); diff --git a/packages/anoma-wallet/src/lib/Keplr.test.ts b/packages/anoma-wallet/src/lib/Keplr.test.ts new file mode 100644 index 00000000000..fafbf911eed --- /dev/null +++ b/packages/anoma-wallet/src/lib/Keplr.test.ts @@ -0,0 +1,69 @@ +import { ChainInfo } from "@keplr-wallet/types"; +import { Chain } from "config"; +import Keplr, { KeplrExtension } from "./Keplr"; + +const chain: Chain = { + accountIndex: 0, + alias: "Namada Testnet", + id: "anoma-test.fd58c789bc11e6c6392", + network: { + protocol: "http", + wsProtocol: "ws", + url: "localhost", + port: 26657, + }, +}; + +const keplrExtension: KeplrExtension = { + enable: async (id: string) => { + if (id) { + return; + } + return Promise.reject(); + }, + experimentalSuggestChain: async (chainInfo: ChainInfo) => { + if (chainInfo) { + return; + } + return Promise.reject(); + }, + getKey: async (id: string) => { + if (id) { + return { + name: "keyName", + algo: "algo", + pubKey: new Uint8Array(), + address: new Uint8Array(), + bech32Address: + "atest1v4ehgw36gc6yxvpjxccyzvphxycrxw2xxsuyydesxgcnjs3cg9znwv3cxgmnj32yxy6rssf5tcqjm3", + }; + } + return Promise.reject(); + }, +}; + +const keplr = new Keplr(chain, keplrExtension); + +describe("Keplr class", () => { + test("It should detect keplr extension", () => { + const isKeplrDetected = keplr.detect(); + expect(isKeplrDetected).toEqual(true); + }); + + test("It should invoke suggestChain", async () => { + const results = await keplr.suggestChain(); + expect(results).toEqual(true); + // TODO: Properly mock window.keplr + // expect(keplrExtension.experimentalSuggestChain).toHaveBeenCalled(); + }); + + test("It should invoke enable", async () => { + const results = await keplr.enable(); + expect(results).toEqual(true); + }); + + test("It should return a chain configuration for inspection", () => { + const chainConfig = keplr.chain; + expect(chainConfig).toBe(chain); + }); +}); diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index 1413e16c417..0e5c0d56840 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -8,20 +8,22 @@ const { REACT_APP_LOCAL, NODE_ENV } = process.env; const PREFIX = "namada"; const PREFIX_TESTNET = "atest"; +export type KeplrExtension = { + experimentalSuggestChain: (chainInfo: ChainInfo) => Promise; + enable: (chainId: string) => Promise; + getKey: (chainId: string) => Promise<{ + // Name of the selected key store. + name: string; + algo: string; + pubKey: Uint8Array; + address: Uint8Array; + bech32Address: string; + }>; +}; + type WindowWithKeplr = Window & typeof globalThis & { - keplr: { - experimentalSuggestChain: (chainInfo: ChainInfo) => Promise; - enable: (chainId: string) => Promise; - getKey: (chainId: string) => Promise<{ - // Name of the selected key store. - name: string; - algo: string; - pubKey: Uint8Array; - address: Uint8Array; - bech32Address: string; - }>; - }; + keplr: KeplrExtension; }; class Keplr { From 821fe685a8ffda267ce618be7eaf76de12d39bb1 Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Wed, 3 Aug 2022 04:51:37 -0400 Subject: [PATCH 09/36] Add tests to ensure keplr extension methods get called appropriately --- packages/anoma-wallet/src/lib/Keplr.test.ts | 131 +++++++++++++++----- packages/anoma-wallet/src/lib/Keplr.ts | 29 +++-- 2 files changed, 119 insertions(+), 41 deletions(-) diff --git a/packages/anoma-wallet/src/lib/Keplr.test.ts b/packages/anoma-wallet/src/lib/Keplr.test.ts index fafbf911eed..0f3fbc14866 100644 --- a/packages/anoma-wallet/src/lib/Keplr.test.ts +++ b/packages/anoma-wallet/src/lib/Keplr.test.ts @@ -2,26 +2,17 @@ import { ChainInfo } from "@keplr-wallet/types"; import { Chain } from "config"; import Keplr, { KeplrExtension } from "./Keplr"; -const chain: Chain = { - accountIndex: 0, - alias: "Namada Testnet", - id: "anoma-test.fd58c789bc11e6c6392", - network: { - protocol: "http", - wsProtocol: "ws", - url: "localhost", - port: 26657, - }, -}; - -const keplrExtension: KeplrExtension = { - enable: async (id: string) => { +/** + * Mock Keplr extension + */ +const mockKeplrExtension: KeplrExtension = { + enable: async (id: string): Promise => { if (id) { return; } return Promise.reject(); }, - experimentalSuggestChain: async (chainInfo: ChainInfo) => { + experimentalSuggestChain: async (chainInfo: ChainInfo): Promise => { if (chainInfo) { return; } @@ -29,41 +20,119 @@ const keplrExtension: KeplrExtension = { }, getKey: async (id: string) => { if (id) { - return { - name: "keyName", - algo: "algo", - pubKey: new Uint8Array(), - address: new Uint8Array(), - bech32Address: - "atest1v4ehgw36gc6yxvpjxccyzvphxycrxw2xxsuyydesxgcnjs3cg9znwv3cxgmnj32yxy6rssf5tcqjm3", - }; + return mockKey; } return Promise.reject(); }, }; -const keplr = new Keplr(chain, keplrExtension); +/** + * Mock Chain configuration data + */ +const mockChain: Chain = { + accountIndex: 0, + alias: "Namada Testnet", + id: "anoma-test.fd58c789bc11e6c6392", + network: { + protocol: "http", + wsProtocol: "ws", + url: "localhost", + port: 26657, + }, +}; + +/** + * Mock Keplr key results data + */ +const mockKey = { + name: "keyName", + algo: "algo", + pubKey: new Uint8Array(), + address: new Uint8Array(), + bech32Address: + "atest1v4ehgw36gc6yxvpjxccyzvphxycrxw2xxsuyydesxgcnjs3cg9znwv3cxgmnj32yxy6rssf5tcqjm3", +}; + +/** + * Mock Chain Info data for Keplr suggest chain + */ +const mockChainInfo = { + rpc: "http://localhost:26657", + rest: "http://localhost:1317", + chainId: "anoma-test.fd58c789bc11e6c6392", + chainName: "Namada Testnet", + stakeCurrency: { + coinDenom: "ATOM", + coinMinimalDenom: "uatom", + coinDecimals: 6, + coinGeckoId: "cosmos", + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: "namada", + bech32PrefixAccPub: "namadapub", + bech32PrefixValAddr: "namadavaloper", + bech32PrefixValPub: "namadavaloperpub", + bech32PrefixConsAddr: "namadavalcons", + bech32PrefixConsPub: "namadavalconspub", + }, + currencies: [ + { + coinDenom: "ATOM", + coinMinimalDenom: "uatom", + coinDecimals: 6, + coinGeckoId: "cosmos", + }, + ], + feeCurrencies: [ + { + coinDenom: "ATOM", + coinMinimalDenom: "uatom", + coinDecimals: 6, + coinGeckoId: "cosmos", + }, + ], + gasPriceStep: { low: 0.01, average: 0.025, high: 0.03 }, +}; + +const mockKeplr = new Keplr(mockChain, mockKeplrExtension); describe("Keplr class", () => { test("It should detect keplr extension", () => { - const isKeplrDetected = keplr.detect(); + const isKeplrDetected = mockKeplr.detect(); + expect(isKeplrDetected).toEqual(true); }); test("It should invoke suggestChain", async () => { - const results = await keplr.suggestChain(); + const spy = jest.spyOn(mockKeplr.instance, "experimentalSuggestChain"); + const results = await mockKeplr.suggestChain(); + expect(results).toEqual(true); - // TODO: Properly mock window.keplr - // expect(keplrExtension.experimentalSuggestChain).toHaveBeenCalled(); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(mockChainInfo); }); test("It should invoke enable", async () => { - const results = await keplr.enable(); + const spy = jest.spyOn(mockKeplr.instance, "enable"); + const results = await mockKeplr.enable(); + expect(results).toEqual(true); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(mockChain.id); + }); + + test("It should invoke getKey", async () => { + const spy = jest.spyOn(mockKeplr.instance, "getKey"); + const results = await mockKeplr.getKey(); + + expect(results).toBe(mockKey); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(mockChain.id); }); test("It should return a chain configuration for inspection", () => { - const chainConfig = keplr.chain; - expect(chainConfig).toBe(chain); + const chainConfig = mockKeplr.chain; + expect(chainConfig).toBe(mockChain); }); }); diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index 0e5c0d56840..680856668dc 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -8,17 +8,19 @@ const { REACT_APP_LOCAL, NODE_ENV } = process.env; const PREFIX = "namada"; const PREFIX_TESTNET = "atest"; +type KeplrKey = { + // Name of the selected key store. + name: string; + algo: string; + pubKey: Uint8Array; + address: Uint8Array; + bech32Address: string; +}; + export type KeplrExtension = { experimentalSuggestChain: (chainInfo: ChainInfo) => Promise; enable: (chainId: string) => Promise; - getKey: (chainId: string) => Promise<{ - // Name of the selected key store. - name: string; - algo: string; - pubKey: Uint8Array; - address: Uint8Array; - bech32Address: string; - }>; + getKey: (chainId: string) => Promise; }; type WindowWithKeplr = Window & @@ -46,6 +48,13 @@ class Keplr { return this._chain; } + /** + * Keplr extension accessor + */ + public get instance(): KeplrExtension { + return this._keplr; + } + /** * Determine if keplr extension is loaded * @returns {boolean} @@ -74,13 +83,13 @@ class Keplr { * Get key for current chain * @returns {Promise { + public async getKey(): Promise { if (this._keplr) { const { id } = this._chain; return this._keplr .getKey(id) - .then(() => true) + .then((results) => results) .catch(() => Promise.reject(false)); } return Promise.reject(false); From b45ed131a66fe514fd51a3427b3fc78cfeb4a17a Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Wed, 3 Aug 2022 05:23:11 -0400 Subject: [PATCH 10/36] Improve types, reuse from keplr types --- packages/anoma-wallet/src/lib/Keplr.test.ts | 48 +++++++++------------ packages/anoma-wallet/src/lib/Keplr.ts | 26 ++++------- 2 files changed, 28 insertions(+), 46 deletions(-) diff --git a/packages/anoma-wallet/src/lib/Keplr.test.ts b/packages/anoma-wallet/src/lib/Keplr.test.ts index 0f3fbc14866..0c586e4631e 100644 --- a/packages/anoma-wallet/src/lib/Keplr.test.ts +++ b/packages/anoma-wallet/src/lib/Keplr.test.ts @@ -1,31 +1,7 @@ -import { ChainInfo } from "@keplr-wallet/types"; +import { ChainInfo, Key } from "@keplr-wallet/types"; import { Chain } from "config"; import Keplr, { KeplrExtension } from "./Keplr"; -/** - * Mock Keplr extension - */ -const mockKeplrExtension: KeplrExtension = { - enable: async (id: string): Promise => { - if (id) { - return; - } - return Promise.reject(); - }, - experimentalSuggestChain: async (chainInfo: ChainInfo): Promise => { - if (chainInfo) { - return; - } - return Promise.reject(); - }, - getKey: async (id: string) => { - if (id) { - return mockKey; - } - return Promise.reject(); - }, -}; - /** * Mock Chain configuration data */ @@ -44,19 +20,20 @@ const mockChain: Chain = { /** * Mock Keplr key results data */ -const mockKey = { +const mockKey: Key = { name: "keyName", algo: "algo", pubKey: new Uint8Array(), address: new Uint8Array(), bech32Address: "atest1v4ehgw36gc6yxvpjxccyzvphxycrxw2xxsuyydesxgcnjs3cg9znwv3cxgmnj32yxy6rssf5tcqjm3", + isNanoLedger: false, }; /** - * Mock Chain Info data for Keplr suggest chain + * Mock Chain Info data for Keplr suggest chain functionality */ -const mockChainInfo = { +const mockChainInfo: ChainInfo = { rpc: "http://localhost:26657", rest: "http://localhost:1317", chainId: "anoma-test.fd58c789bc11e6c6392", @@ -95,6 +72,21 @@ const mockChainInfo = { gasPriceStep: { low: 0.01, average: 0.025, high: 0.03 }, }; +/** + * Mock Keplr extension + */ +const mockKeplrExtension: KeplrExtension = { + enable: async (): Promise => { + return; + }, + experimentalSuggestChain: async (): Promise => { + return; + }, + getKey: async (): Promise => { + return mockKey; + }, +}; + const mockKeplr = new Keplr(mockChain, mockKeplrExtension); describe("Keplr class", () => { diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index 680856668dc..9f4702c2110 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -1,4 +1,4 @@ -import { ChainInfo } from "@keplr-wallet/types"; +import { Keplr as KeplrInterface, ChainInfo, Key } from "@keplr-wallet/types"; import { Chain } from "config"; import { Tokens, TokenType } from "constants/"; @@ -8,24 +8,14 @@ const { REACT_APP_LOCAL, NODE_ENV } = process.env; const PREFIX = "namada"; const PREFIX_TESTNET = "atest"; -type KeplrKey = { - // Name of the selected key store. - name: string; - algo: string; - pubKey: Uint8Array; - address: Uint8Array; - bech32Address: string; -}; - -export type KeplrExtension = { - experimentalSuggestChain: (chainInfo: ChainInfo) => Promise; - enable: (chainId: string) => Promise; - getKey: (chainId: string) => Promise; -}; +export type KeplrExtension = Pick< + KeplrInterface, + "enable" | "getKey" | "experimentalSuggestChain" +>; type WindowWithKeplr = Window & typeof globalThis & { - keplr: KeplrExtension; + keplr: KeplrInterface | KeplrExtension; }; class Keplr { @@ -83,13 +73,13 @@ class Keplr { * Get key for current chain * @returns {Promise { + public async getKey(): Promise { if (this._keplr) { const { id } = this._chain; return this._keplr .getKey(id) - .then((results) => results) + .then((key) => key) .catch(() => Promise.reject(false)); } return Promise.reject(false); From adc8bab6d4749fb5a1979d09cc2ecaaddc83b9c7 Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Wed, 3 Aug 2022 05:38:47 -0400 Subject: [PATCH 11/36] Remove unused lib and associated test --- packages/anoma-wallet/src/lib/Keypair.test.ts | 52 ------------------- packages/anoma-wallet/src/lib/Keypair.ts | 39 -------------- packages/anoma-wallet/src/lib/index.ts | 1 - 3 files changed, 92 deletions(-) delete mode 100644 packages/anoma-wallet/src/lib/Keypair.test.ts delete mode 100644 packages/anoma-wallet/src/lib/Keypair.ts diff --git a/packages/anoma-wallet/src/lib/Keypair.test.ts b/packages/anoma-wallet/src/lib/Keypair.test.ts deleted file mode 100644 index a580926cbf6..00000000000 --- a/packages/anoma-wallet/src/lib/Keypair.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { AnomaClient, Keypair as NativeKeypair } from "@namada-interface/anoma-lib"; -import Keypair from "./Keypair"; - -const KEYPAIR = { - secret: "F003E045C9943C35704F506B657FBA06B0A271E03E08B7BB7CEAF4FB5C2477F3", - public: "572512A95B190D615B1987F7072572A64951AD50F4F97EF9DBB83545C46AE600", -}; - -const SERIALIZABLE_KEYPAIR = { - public: new Uint8Array([ - 87, 37, 18, 169, 91, 25, 13, 97, 91, 25, 135, 247, 7, 37, 114, 166, 73, 81, - 173, 80, 244, 249, 126, 249, 219, 184, 53, 69, 196, 106, 230, 0, - ]), - secret: new Uint8Array([ - 240, 3, 224, 69, 201, 148, 60, 53, 112, 79, 80, 107, 101, 127, 186, 6, 176, - 162, 113, 224, 62, 8, 183, 187, 124, 234, 244, 251, 92, 36, 119, 243, - ]), -}; - -// Pointer object properties: -const props = ["ptr"]; - -describe("Keypair wasm and class methods", () => { - test("Keypair should be able to be serialized to a native type", async () => { - const keypair = new Keypair(KEYPAIR); - const nativeKeypair: NativeKeypair = await keypair.toNativeKeypair(); - - expect(Object.keys(nativeKeypair)).toEqual(expect.arrayContaining(props)); - const jsValue = nativeKeypair.from_pointer_to_js_value(); - - expect({ - secret: new Uint8Array(jsValue.secret), - public: new Uint8Array(jsValue.public), - }).toEqual(SERIALIZABLE_KEYPAIR); - expect(nativeKeypair.to_bytes().length).toBe(64); - }); - - test("Keypair should be able to return a serializable keypair type", () => { - const keypair = new Keypair(KEYPAIR); - const { serializable } = keypair; - expect(serializable).toEqual(SERIALIZABLE_KEYPAIR); - }); - - test("JS Data should be able to be deserialized to native Keypair type", async () => { - // First, create a native Keypair (from wasm) - const { keypair } = await new AnomaClient().init(); - - // Now, we have access to the static method "deserialize" - const deserialized = keypair.from_js_value_to_pointer(SERIALIZABLE_KEYPAIR); - expect(Object.keys(deserialized)).toEqual(expect.arrayContaining(props)); - }); -}); diff --git a/packages/anoma-wallet/src/lib/Keypair.ts b/packages/anoma-wallet/src/lib/Keypair.ts deleted file mode 100644 index a7d2f5b1c2b..00000000000 --- a/packages/anoma-wallet/src/lib/Keypair.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { fromHex } from "@cosmjs/encoding"; -import { AnomaClient, Keypair as NativeKeypair } from "@namada-interface/anoma-lib"; - -type KeypairArgs = { - public: string; - secret: string; -}; - -export type SerializableKeypair = { - public: Uint8Array; - secret: Uint8Array; -}; - -class Keypair { - private _public: string; - private _secret: string; - - constructor(args: KeypairArgs) { - this._public = args.public; - this._secret = args.secret; - } - - public get serializable(): SerializableKeypair { - return { - public: fromHex(this._public), - secret: fromHex(this._secret), - }; - } - - /** - * Convert to native Anoma keypair - */ - public async toNativeKeypair(): Promise { - const { keypair } = await new AnomaClient().init(); - return keypair.from_js_value_to_pointer(this.serializable); - } -} - -export default Keypair; diff --git a/packages/anoma-wallet/src/lib/index.ts b/packages/anoma-wallet/src/lib/index.ts index c59135cd230..95482f74d23 100644 --- a/packages/anoma-wallet/src/lib/index.ts +++ b/packages/anoma-wallet/src/lib/index.ts @@ -1,7 +1,6 @@ export { default as Account } from "lib/tx/Account"; export { default as IBCTransfer } from "lib/tx/IBCTransfer"; export { default as Keplr } from "lib/Keplr"; -export { default as Keypair } from "lib/Keypair"; export { default as RpcClient } from "lib/rpc/RpcClient"; export { default as Session } from "lib/Session"; export { default as SocketClient } from "lib/rpc/SocketClient"; From 7f4d1c9c817d97d80f44a18cad42517bfd22078d Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Wed, 3 Aug 2022 06:30:09 -0400 Subject: [PATCH 12/36] Give basic feedback if Keplr is not detected --- .../SettingsWalletSettings.components.ts | 4 ++++ .../SettingsWalletSettings/SettingsWalletSettings.tsx | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.components.ts b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.components.ts index 48a4ba657fc..0809ad886e0 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.components.ts +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.components.ts @@ -8,3 +8,7 @@ export const SettingsWalletSettingsContainer = styled.div` width: 100%; height: 100%; `; + +export const ExtensionInfo = styled.p` + padding: 20px; +`; diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx index d91fb077043..1c3cc04e135 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx @@ -9,7 +9,10 @@ import { Currencies } from "constants/"; import { NavigationContainer } from "components/NavigationContainer"; import { Heading, HeadingLevel } from "components/Heading"; -import { SettingsWalletSettingsContainer } from "./SettingsWalletSettings.components"; +import { + ExtensionInfo, + SettingsWalletSettingsContainer, +} from "./SettingsWalletSettings.components"; import { Tooltip } from "components/Tooltip"; import { Icon, IconName } from "components/Icon"; import { Select, Option } from "components/Select"; @@ -168,7 +171,7 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { /> - {keplr.detect() && ( + {keplr.detect() ? ( <> + ) : ( + + Install the Keplr extension to connect your Wallet + )} From 6e8a16b1d4cecf18dc5e460296191e30f98dff8e Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Wed, 3 Aug 2022 08:20:44 -0400 Subject: [PATCH 13/36] Clean up --- packages/anoma-wallet/src/lib/Keplr.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index 9f4702c2110..ce404c3f903 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -1,4 +1,4 @@ -import { Keplr as KeplrInterface, ChainInfo, Key } from "@keplr-wallet/types"; +import { Keplr as IKeplr, ChainInfo, Key } from "@keplr-wallet/types"; import { Chain } from "config"; import { Tokens, TokenType } from "constants/"; @@ -9,13 +9,13 @@ const PREFIX = "namada"; const PREFIX_TESTNET = "atest"; export type KeplrExtension = Pick< - KeplrInterface, + IKeplr, "enable" | "getKey" | "experimentalSuggestChain" >; type WindowWithKeplr = Window & typeof globalThis & { - keplr: KeplrInterface | KeplrExtension; + keplr: IKeplr | KeplrExtension; }; class Keplr { @@ -122,11 +122,11 @@ class Keplr { }, bech32Config: { bech32PrefixAccAddr: bech32Prefix, - bech32PrefixAccPub: bech32Prefix + "pub", - bech32PrefixValAddr: bech32Prefix + "valoper", - bech32PrefixValPub: bech32Prefix + "valoperpub", - bech32PrefixConsAddr: bech32Prefix + "valcons", - bech32PrefixConsPub: bech32Prefix + "valconspub", + bech32PrefixAccPub: `${bech32Prefix}pub`, + bech32PrefixValAddr: `${bech32Prefix}valoper`, + bech32PrefixValPub: `${bech32Prefix}valoperpub`, + bech32PrefixConsAddr: `${bech32Prefix}valcons`, + bech32PrefixConsPub: `${bech32Prefix}valconspub`, }, currencies: [currency], feeCurrencies: [currency], @@ -138,6 +138,7 @@ class Keplr { .then(() => true) .catch(() => Promise.reject(false)); } + return Promise.reject(false); } } From 82797515fa202b2ab79ba30b6fad085fc35acba4 Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Wed, 3 Aug 2022 10:43:54 -0400 Subject: [PATCH 14/36] Improve usage of types, better detection of Keplr connection --- .../SettingsWalletSettings.tsx | 59 ++++++++++++------- packages/anoma-wallet/src/lib/Keplr.test.ts | 22 ++++--- packages/anoma-wallet/src/lib/Keplr.ts | 21 +++---- 3 files changed, 61 insertions(+), 41 deletions(-) diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx index 1c3cc04e135..989f37d21bb 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx @@ -1,6 +1,5 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; - import { Chain } from "config/chain"; import { setFiatCurrency, setChainId, SettingsState } from "slices/settings"; import { useAppDispatch, useAppSelector } from "store"; @@ -40,12 +39,15 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { const { chainId } = useAppSelector((state) => state.settings); const chain = Config.chain[chainId]; const keplr = new Keplr(chain); + const offlineSigner = keplr.instance?.getOfflineSigner(chainId); const [displaySeedPhrase, setDisplaySeedPhrase] = useState(false); const [seedPhrase, setSeedPhrase] = useState([]); const [isLoadingSeed, setIsLoadingSeed] = useState(false); const [isKeplrAddingChain, setIsKeplrAddingChain] = useState(false); + const [isKeplrChainAdded, setIsKeplrChainAdded] = useState(false); const [isKeplrConnecting, setIsKeplrConnecting] = useState(false); + const [isKeplrConnected, setIsKeplrConnected] = useState(false); const networks = Object.values(chains).map(({ id, alias }: Chain) => ({ label: alias, @@ -73,6 +75,12 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { (state) => state.settings.fiatCurrency ); + useEffect(() => { + if (offlineSigner) { + setIsKeplrChainAdded(true); + } + }, []); + const handleCurrencySelect = ( e: React.ChangeEvent ): void => { @@ -101,6 +109,10 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { setIsKeplrConnecting(true); if (keplr.detect()) { await keplr.enable(); + const key = await keplr.getKey(); + if (key) { + setIsKeplrConnected(true); + } setIsKeplrConnecting(false); } }; @@ -171,26 +183,31 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { /> - {keplr.detect() ? ( - <> - - - + {!isKeplrChainAdded && ( + + )} + + {!isKeplrConnected ? ( + ) : ( + Connected to Keplr Extension + )} + + {!keplr.detect() && ( Install the Keplr extension to connect your Wallet diff --git a/packages/anoma-wallet/src/lib/Keplr.test.ts b/packages/anoma-wallet/src/lib/Keplr.test.ts index 0c586e4631e..82d8e14bec3 100644 --- a/packages/anoma-wallet/src/lib/Keplr.test.ts +++ b/packages/anoma-wallet/src/lib/Keplr.test.ts @@ -1,6 +1,8 @@ -import { ChainInfo, Key } from "@keplr-wallet/types"; +import { ChainInfo, Key, Keplr as IKeplr } from "@keplr-wallet/types"; import { Chain } from "config"; -import Keplr, { KeplrExtension } from "./Keplr"; +import Keplr from "./Keplr"; + +type MockKeplr = Pick; /** * Mock Chain configuration data @@ -75,7 +77,7 @@ const mockChainInfo: ChainInfo = { /** * Mock Keplr extension */ -const mockKeplrExtension: KeplrExtension = { +const mockKeplrExtension: MockKeplr = { enable: async (): Promise => { return; }, @@ -87,7 +89,7 @@ const mockKeplrExtension: KeplrExtension = { }, }; -const mockKeplr = new Keplr(mockChain, mockKeplrExtension); +const mockKeplr = new Keplr(mockChain, mockKeplrExtension as IKeplr); describe("Keplr class", () => { test("It should detect keplr extension", () => { @@ -97,7 +99,9 @@ describe("Keplr class", () => { }); test("It should invoke suggestChain", async () => { - const spy = jest.spyOn(mockKeplr.instance, "experimentalSuggestChain"); + const spy = mockKeplr.instance + ? jest.spyOn(mockKeplr.instance, "experimentalSuggestChain") + : null; const results = await mockKeplr.suggestChain(); expect(results).toEqual(true); @@ -106,7 +110,9 @@ describe("Keplr class", () => { }); test("It should invoke enable", async () => { - const spy = jest.spyOn(mockKeplr.instance, "enable"); + const spy = mockKeplr.instance + ? jest.spyOn(mockKeplr.instance, "enable") + : null; const results = await mockKeplr.enable(); expect(results).toEqual(true); @@ -115,7 +121,9 @@ describe("Keplr class", () => { }); test("It should invoke getKey", async () => { - const spy = jest.spyOn(mockKeplr.instance, "getKey"); + const spy = mockKeplr.instance + ? jest.spyOn(mockKeplr.instance, "getKey") + : null; const results = await mockKeplr.getKey(); expect(results).toBe(mockKey); diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index ce404c3f903..53dfb89d135 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -1,4 +1,9 @@ -import { Keplr as IKeplr, ChainInfo, Key } from "@keplr-wallet/types"; +import { + Keplr as IKeplr, + ChainInfo, + Key, + Window as KeplrWindow, +} from "@keplr-wallet/types"; import { Chain } from "config"; import { Tokens, TokenType } from "constants/"; @@ -8,16 +13,6 @@ const { REACT_APP_LOCAL, NODE_ENV } = process.env; const PREFIX = "namada"; const PREFIX_TESTNET = "atest"; -export type KeplrExtension = Pick< - IKeplr, - "enable" | "getKey" | "experimentalSuggestChain" ->; - -type WindowWithKeplr = Window & - typeof globalThis & { - keplr: IKeplr | KeplrExtension; - }; - class Keplr { /** * Pass a chain config into constructor to instantiate, and optionally @@ -27,7 +22,7 @@ class Keplr { */ constructor( private _chain: Chain, - private _keplr = (window)?.keplr + private _keplr = (window)?.keplr ) {} /** @@ -41,7 +36,7 @@ class Keplr { /** * Keplr extension accessor */ - public get instance(): KeplrExtension { + public get instance(): IKeplr | undefined { return this._keplr; } From 84496c547766c23e8466bd9164fbfaa25d975fbb Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Wed, 3 Aug 2022 11:21:42 -0400 Subject: [PATCH 15/36] Properly detect whether chain has been added to keplr --- .../SettingsWalletSettings.tsx | 45 +++++++++++++------ packages/anoma-wallet/src/lib/Keplr.ts | 33 ++++++-------- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx index 989f37d21bb..efd55c8d000 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx @@ -39,7 +39,6 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { const { chainId } = useAppSelector((state) => state.settings); const chain = Config.chain[chainId]; const keplr = new Keplr(chain); - const offlineSigner = keplr.instance?.getOfflineSigner(chainId); const [displaySeedPhrase, setDisplaySeedPhrase] = useState(false); const [seedPhrase, setSeedPhrase] = useState([]); @@ -76,10 +75,16 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { ); useEffect(() => { - if (offlineSigner) { - setIsKeplrChainAdded(true); - } - }, []); + (async () => { + try { + await keplr.instance?.getOfflineSignerAuto(chainId); + setIsKeplrChainAdded(true); + } catch (e) { + setIsKeplrChainAdded(false); + setIsKeplrConnected(false); + } + })(); + }, [chainId]); const handleCurrencySelect = ( e: React.ChangeEvent @@ -100,20 +105,30 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { const handleKeplrSuggestChainClick = async (): Promise => { setIsKeplrAddingChain(true); if (keplr.detect()) { - await keplr.suggestChain(); - setIsKeplrAddingChain(false); + try { + await keplr.suggestChain(); + setIsKeplrAddingChain(false); + } catch (e) { + console.warn(e); + setIsKeplrAddingChain(false); + } } }; const handleKeplrEnableClick = async (): Promise => { setIsKeplrConnecting(true); if (keplr.detect()) { - await keplr.enable(); - const key = await keplr.getKey(); - if (key) { - setIsKeplrConnected(true); + try { + await keplr.enable(); + const key = await keplr.getKey(); + if (key) { + setIsKeplrConnected(true); + } + setIsKeplrConnecting(false); + } catch (e) { + console.warn(e); + setIsKeplrConnecting(false); } - setIsKeplrConnecting(false); } }; @@ -194,7 +209,7 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { )} - {!isKeplrConnected ? ( + {isKeplrChainAdded && !isKeplrConnected && ( - ) : ( + )} + + {isKeplrConnected && ( Connected to Keplr Extension )} diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index 53dfb89d135..f8adca2ae6d 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -26,18 +26,19 @@ class Keplr { ) {} /** - * Chain accessor get method - * @returns {Chain} + * Keplr extension accessor + * @returns {IKeplr | undefined} */ - public get chain(): Chain { - return this._chain; + public get instance(): IKeplr | undefined { + return this._keplr; } /** - * Keplr extension accessor + * Chain config accessor + * @returns {Chain} */ - public get instance(): IKeplr | undefined { - return this._keplr; + public get chain(): Chain { + return this._chain; } /** @@ -56,10 +57,8 @@ class Keplr { if (this._keplr) { const { id } = this._chain; - return this._keplr - .enable(id) - .then(() => true) - .catch(() => Promise.reject(false)); + await this._keplr.enable(id); + return true; } return Promise.reject(false); } @@ -71,11 +70,7 @@ class Keplr { public async getKey(): Promise { if (this._keplr) { const { id } = this._chain; - - return this._keplr - .getKey(id) - .then((key) => key) - .catch(() => Promise.reject(false)); + return await this._keplr.getKey(id); } return Promise.reject(false); } @@ -128,10 +123,8 @@ class Keplr { gasPriceStep: { low: 0.01, average: 0.025, high: 0.03 }, // This is optional! }; - return this._keplr - .experimentalSuggestChain(chainInfo) - .then(() => true) - .catch(() => Promise.reject(false)); + await this._keplr.experimentalSuggestChain(chainInfo); + return true; } return Promise.reject(false); From 8630d9ecb759f1b1bfdbb7f741e2b0ad5a647fc6 Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Wed, 3 Aug 2022 12:25:20 -0400 Subject: [PATCH 16/36] Add test for error on getOfflineSignerAuto --- packages/anoma-wallet/src/lib/Keplr.test.ts | 36 +++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/packages/anoma-wallet/src/lib/Keplr.test.ts b/packages/anoma-wallet/src/lib/Keplr.test.ts index 82d8e14bec3..9510ca9b0ce 100644 --- a/packages/anoma-wallet/src/lib/Keplr.test.ts +++ b/packages/anoma-wallet/src/lib/Keplr.test.ts @@ -1,8 +1,16 @@ import { ChainInfo, Key, Keplr as IKeplr } from "@keplr-wallet/types"; import { Chain } from "config"; + import Keplr from "./Keplr"; -type MockKeplr = Pick; +type MockKeplr = Pick< + IKeplr, + "enable" | "getKey" | "experimentalSuggestChain" | "getOfflineSignerAuto" +>; + +type ErrorMessage = { + message: string; +}; /** * Mock Chain configuration data @@ -27,8 +35,7 @@ const mockKey: Key = { algo: "algo", pubKey: new Uint8Array(), address: new Uint8Array(), - bech32Address: - "atest1v4ehgw36gc6yxvpjxccyzvphxycrxw2xxsuyydesxgcnjs3cg9znwv3cxgmnj32yxy6rssf5tcqjm3", + bech32Address: "cosmos1qjnyxraddqgzg91ezty2x3n5t31eur9dsxx4fp", isNanoLedger: false, }; @@ -87,6 +94,15 @@ const mockKeplrExtension: MockKeplr = { getKey: async (): Promise => { return mockKey; }, + // We don't have types we can import for OfflineSigner, and we currently only want + // to ensure an error is raised if the provided chainId doesn't match the + // keplr instance, hence the following any: + // eslint-disable-next-line @typescript-eslint/no-explicit-any + getOfflineSignerAuto: async (chainId: string): Promise => { + if (mockChain.id !== chainId) { + throw new Error("Chain not found"); + } + }, }; const mockKeplr = new Keplr(mockChain, mockKeplrExtension as IKeplr); @@ -136,3 +152,17 @@ describe("Keplr class", () => { expect(chainConfig).toBe(mockChain); }); }); + +describe("Keplr.instance.getOfflineSignerAuto", () => { + test("It should throw an error if chain not found", async () => { + expect.assertions(2); + try { + await mockKeplr.instance?.getOfflineSignerAuto( + "anoma-test.008d3ba61b7bb1852c9" + ); + } catch (e: unknown) { + expect(e).toBeInstanceOf(Error); + expect((e as ErrorMessage).message).toEqual("Chain not found"); + } + }); +}); From fd948690c99502487b262dfabad1b9d81e7f28bc Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Thu, 4 Aug 2022 05:45:03 -0400 Subject: [PATCH 17/36] Catch error from Keplr, update tests --- .../SettingsWalletSettings.tsx | 6 +- packages/anoma-wallet/src/lib/Keplr.test.ts | 56 ++++++++++++------- packages/anoma-wallet/src/lib/Keplr.ts | 25 ++++++++- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx index efd55c8d000..8e7ad0c4aee 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx @@ -76,10 +76,10 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { useEffect(() => { (async () => { - try { - await keplr.instance?.getOfflineSignerAuto(chainId); + const isChainAdded = await keplr.detectChain(); + if (isChainAdded) { setIsKeplrChainAdded(true); - } catch (e) { + } else { setIsKeplrChainAdded(false); setIsKeplrConnected(false); } diff --git a/packages/anoma-wallet/src/lib/Keplr.test.ts b/packages/anoma-wallet/src/lib/Keplr.test.ts index 9510ca9b0ce..01a5f883b12 100644 --- a/packages/anoma-wallet/src/lib/Keplr.test.ts +++ b/packages/anoma-wallet/src/lib/Keplr.test.ts @@ -8,9 +8,7 @@ type MockKeplr = Pick< "enable" | "getKey" | "experimentalSuggestChain" | "getOfflineSignerAuto" >; -type ErrorMessage = { - message: string; -}; +const KEPLR_ADDED_CHAINS = ["anoma-test.fd58c789bc11e6c6392"]; /** * Mock Chain configuration data @@ -99,8 +97,8 @@ const mockKeplrExtension: MockKeplr = { // keplr instance, hence the following any: // eslint-disable-next-line @typescript-eslint/no-explicit-any getOfflineSignerAuto: async (chainId: string): Promise => { - if (mockChain.id !== chainId) { - throw new Error("Chain not found"); + if (KEPLR_ADDED_CHAINS.indexOf(chainId) < 0) { + throw new Error("Chain not found!"); } }, }; @@ -123,6 +121,7 @@ describe("Keplr class", () => { expect(results).toEqual(true); expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledWith(mockChainInfo); + spy?.mockRestore(); }); test("It should invoke enable", async () => { @@ -134,6 +133,7 @@ describe("Keplr class", () => { expect(results).toEqual(true); expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledWith(mockChain.id); + spy?.mockRestore(); }); test("It should invoke getKey", async () => { @@ -145,6 +145,38 @@ describe("Keplr class", () => { expect(results).toBe(mockKey); expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledWith(mockChain.id); + spy?.mockRestore(); + }); + + test("It should invoke detectChain", async () => { + const spy = mockKeplr.instance + ? jest.spyOn(mockKeplr.instance, "getOfflineSignerAuto") + : null; + const results = await mockKeplr.detectChain(); + + expect(results).toEqual(true); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenLastCalledWith(mockChain.id); + spy?.mockRestore(); + }); + + test("It should catch raised error if chainId not found in detectChain", async () => { + const invalidChain = { ...mockChain, id: "anoma-ibc-0.4.5b0d5e5569aa27fb" }; + const mockKeplrInvalidChainId = new Keplr( + invalidChain, + mockKeplrExtension as IKeplr + ); + + const spy = mockKeplrInvalidChainId.instance + ? jest.spyOn(mockKeplrInvalidChainId.instance, "getOfflineSignerAuto") + : null; + + const results = await mockKeplrInvalidChainId.detectChain(); + + expect(results).toEqual(false); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(invalidChain.id); + spy?.mockRestore(); }); test("It should return a chain configuration for inspection", () => { @@ -152,17 +184,3 @@ describe("Keplr class", () => { expect(chainConfig).toBe(mockChain); }); }); - -describe("Keplr.instance.getOfflineSignerAuto", () => { - test("It should throw an error if chain not found", async () => { - expect.assertions(2); - try { - await mockKeplr.instance?.getOfflineSignerAuto( - "anoma-test.008d3ba61b7bb1852c9" - ); - } catch (e: unknown) { - expect(e).toBeInstanceOf(Error); - expect((e as ErrorMessage).message).toEqual("Chain not found"); - } - }); -}); diff --git a/packages/anoma-wallet/src/lib/Keplr.ts b/packages/anoma-wallet/src/lib/Keplr.ts index f8adca2ae6d..43210abacab 100644 --- a/packages/anoma-wallet/src/lib/Keplr.ts +++ b/packages/anoma-wallet/src/lib/Keplr.ts @@ -12,6 +12,7 @@ const { REACT_APP_LOCAL, NODE_ENV } = process.env; const PREFIX = "namada"; const PREFIX_TESTNET = "atest"; +const KEPLR_NOT_FOUND = "Keplr extension not found!"; class Keplr { /** @@ -49,6 +50,24 @@ class Keplr { return !!this._keplr; } + /** + * Determine if chain has been added to extension. Keplr + * will throw an error if chain is not found + * @returns {Promise} + */ + public async detectChain(): Promise { + if (this._keplr) { + try { + await this._keplr.getOfflineSignerAuto(this._chain.id); + return true; + } catch (e) { + console.warn(e); + return false; + } + } + return Promise.reject(KEPLR_NOT_FOUND); + } + /** * Enable connection to Keplr for current chain * @returns {Promise} @@ -60,7 +79,7 @@ class Keplr { await this._keplr.enable(id); return true; } - return Promise.reject(false); + return Promise.reject(KEPLR_NOT_FOUND); } /** @@ -72,7 +91,7 @@ class Keplr { const { id } = this._chain; return await this._keplr.getKey(id); } - return Promise.reject(false); + return Promise.reject(KEPLR_NOT_FOUND); } /** @@ -127,7 +146,7 @@ class Keplr { return true; } - return Promise.reject(false); + return Promise.reject(KEPLR_NOT_FOUND); } } From 6c7a9832be92a00ea44794157e8eba5938045ec3 Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Thu, 4 Aug 2022 05:53:23 -0400 Subject: [PATCH 18/36] Better handling of keplr extension not found --- .../SettingsWalletSettings.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx index 8e7ad0c4aee..d6b90751e9d 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx @@ -76,10 +76,16 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { useEffect(() => { (async () => { - const isChainAdded = await keplr.detectChain(); - if (isChainAdded) { - setIsKeplrChainAdded(true); - } else { + try { + const isChainAdded = await keplr.detectChain(); + if (isChainAdded) { + setIsKeplrChainAdded(true); + } else { + setIsKeplrChainAdded(false); + setIsKeplrConnected(false); + } + } catch (e) { + console.warn(e); setIsKeplrChainAdded(false); setIsKeplrConnected(false); } @@ -198,7 +204,7 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => { /> - {!isKeplrChainAdded && ( + {!isKeplrChainAdded && keplr.detect() && ( )} - {isKeplrChainAdded && !isKeplrConnected && ( - - )} + {keplrChainState === KeplrChainState.Added && + keplrConnectionState !== KeplrConnectionState.Connected && ( + + )} - {isKeplrConnected && ( + {keplrConnectionState == KeplrConnectionState.Connected && ( Connected to Keplr Extension )} From 20bd71a6d3d670fa4666f5d3349af5f404477396 Mon Sep 17 00:00:00 2001 From: "Justin R. Evans" Date: Thu, 11 Aug 2022 07:41:19 -0400 Subject: [PATCH 36/36] Clean up styles --- .../src/App/AccountOverview/AccountOverview.components.ts | 1 + .../Settings/SettingsWalletSettings/SettingsWalletSettings.tsx | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/anoma-wallet/src/App/AccountOverview/AccountOverview.components.ts b/packages/anoma-wallet/src/App/AccountOverview/AccountOverview.components.ts index 697259e009a..f4f91befb50 100644 --- a/packages/anoma-wallet/src/App/AccountOverview/AccountOverview.components.ts +++ b/packages/anoma-wallet/src/App/AccountOverview/AccountOverview.components.ts @@ -65,6 +65,7 @@ export const InputContainer = styled.div` width: 100%; justify-content: baseline; padding: 20px; + box-sizing: border-box; input { width: 96%; diff --git a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx index 6657143e123..c382f63614d 100644 --- a/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx +++ b/packages/anoma-wallet/src/App/Settings/SettingsWalletSettings/SettingsWalletSettings.tsx @@ -224,7 +224,6 @@ export const SettingsWalletSettings = ({ password }: Props): JSX.Element => {