Ver Fonte

Client/js: Add Info Registrations (#3035)

* Client/js: Add Info Registrations

Change-Id: Ib123dfe895d88c5574f575b16dfc3e6775d81f2a

* Fix build errors

Change-Id: Ifcacb564fc40f14337ab472ece617a2955b579c5
bruce-riley há 2 anos atrás
pai
commit
1ae38c889a

+ 179 - 103
clients/js/package-lock.json

@@ -10,7 +10,7 @@
       "license": "Apache-2.0",
       "dependencies": {
         "@celo-tools/celo-ethers-wrapper": "^0.1.0",
-        "@certusone/wormhole-sdk": "^0.9.16",
+        "@certusone/wormhole-sdk": "^0.9.18",
         "@cosmjs/encoding": "^0.26.2",
         "@injectivelabs/networks": "^1.10.7",
         "@injectivelabs/sdk-ts": "^1.10.47",
@@ -492,16 +492,16 @@
       }
     },
     "node_modules/@certusone/wormhole-sdk": {
-      "version": "0.9.16",
-      "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.9.16.tgz",
-      "integrity": "sha512-UFcGvMW6yku0Qz4hyFw0H4IKKlUJ2VHrHo0PnSUOfbBf7RfXHKPE9VxsVeCKILbhBzBmECVVP4xF7WlrBBn8/Q==",
+      "version": "0.9.18",
+      "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.9.18.tgz",
+      "integrity": "sha512-0YtrdZmjfiUHL78Yr4FA59ywb+pIevbID/TJpJTp/EKWqm/v+9PS4YBMBEtjpDZR/PSqe6hB8MasF38fUjMGtQ==",
       "dependencies": {
         "@certusone/wormhole-sdk-proto-web": "0.0.6",
         "@certusone/wormhole-sdk-wasm": "^0.0.1",
         "@coral-xyz/borsh": "0.2.6",
-        "@injectivelabs/networks": "1.10.7",
-        "@injectivelabs/sdk-ts": "1.10.47",
-        "@injectivelabs/utils": "1.10.5",
+        "@injectivelabs/networks": "1.10.12",
+        "@injectivelabs/sdk-ts": "1.10.72",
+        "@injectivelabs/utils": "1.10.12",
         "@mysten/sui.js": "0.32.2",
         "@project-serum/anchor": "^0.25.0",
         "@solana/spl-token": "^0.3.5",
@@ -1877,9 +1877,9 @@
       }
     },
     "node_modules/@injectivelabs/core-proto-ts": {
-      "version": "0.0.12",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/core-proto-ts/-/core-proto-ts-0.0.12.tgz",
-      "integrity": "sha512-axdL+KWuv4aORIdYqJQy5k9H+bPsi5Y4KWNcYPxrFQ0FAu+sjpvm5PmbIzBSgv/hnIB2cHcLuKvE3BtEa3vJ/w==",
+      "version": "0.0.14",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/core-proto-ts/-/core-proto-ts-0.0.14.tgz",
+      "integrity": "sha512-NZWlgBzgVrXow9IknFQHvcYKX4QkUD25taRigoNYQK8PDn4+VXd9xM5WFUDRhzm2smTCguyl/+MghpEp4oTPWw==",
       "dependencies": {
         "@injectivelabs/grpc-web": "^0.0.1",
         "google-protobuf": "^3.14.0",
@@ -1916,13 +1916,13 @@
       }
     },
     "node_modules/@injectivelabs/exceptions": {
-      "version": "1.10.5",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.10.5.tgz",
-      "integrity": "sha512-jeAa5GL3dbe9vXykzu54RP2RETZ6m92XzOTFWb3F0UgB1GtGEDKoMYxN8CJn9RYz3buCPcHxMi/+og6FHu+RaQ==",
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.11.0.tgz",
+      "integrity": "sha512-jZ0N4cP1KCyErNEiCARaKt70E8KMTNa9R4a5FrCERX4cFKPxdbWpoQ8Lqga2jfHAgiFcChRJ5JmaSYclFtKf9w==",
       "hasInstallScript": true,
       "dependencies": {
         "@injectivelabs/grpc-web": "^0.0.1",
-        "@injectivelabs/ts-types": "^1.10.4",
+        "@injectivelabs/ts-types": "^1.11.0",
         "http-status-codes": "^2.2.0",
         "link-module-alias": "^1.2.0",
         "shx": "^0.3.2"
@@ -1995,9 +1995,9 @@
       }
     },
     "node_modules/@injectivelabs/mito-proto-ts": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/mito-proto-ts/-/mito-proto-ts-1.0.4.tgz",
-      "integrity": "sha512-8raVmZnaXVbpikMTmnc+OtViBPzgyx2ilezUTZFCNcQzZM01lbJlpd0NbF6K5tG76eJ3Wjwj+YpAdRPNuayZ4A==",
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/mito-proto-ts/-/mito-proto-ts-1.0.9.tgz",
+      "integrity": "sha512-+TZMvJ4SHwcn6SFPdqaiQFZdNhjH7hyRFozY15nOTC2utdGij9jEsjz1NsyOejfYDA0s1z5Wm1SgrMYKaVpAmQ==",
       "dependencies": {
         "@injectivelabs/grpc-web": "^0.0.1",
         "google-protobuf": "^3.14.0",
@@ -2034,22 +2034,22 @@
       }
     },
     "node_modules/@injectivelabs/networks": {
-      "version": "1.10.7",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.10.7.tgz",
-      "integrity": "sha512-qnU3A7FgTVi4bGEMaSsSIN2wTBhKZfV+3fiwU09aX8ZNcWAilMx8d/mlE1naZFAHs7Kf5hFBxzgeSRZa1GJqiA==",
+      "version": "1.10.12",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.10.12.tgz",
+      "integrity": "sha512-tTHyLls1Nik5QTs/S03qqG2y/ITvNwI8CJOQbMmmsr1CL2CdjJBtzRYn9Dyx2p8XgzRFf9hmlybpe20tq9O3SA==",
       "hasInstallScript": true,
       "dependencies": {
-        "@injectivelabs/exceptions": "^1.10.5",
-        "@injectivelabs/ts-types": "^1.10.4",
-        "@injectivelabs/utils": "^1.10.5",
+        "@injectivelabs/exceptions": "^1.10.12",
+        "@injectivelabs/ts-types": "^1.10.12",
+        "@injectivelabs/utils": "^1.10.12",
         "link-module-alias": "^1.2.0",
         "shx": "^0.3.2"
       }
     },
     "node_modules/@injectivelabs/sdk-ts": {
-      "version": "1.10.47",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.10.47.tgz",
-      "integrity": "sha512-G11Cdf5iO6is0qWzQRdfiUJLI8IPF4VtD5mVfBwnakrk78syN/Dy492trL7hispDSQaCJaP6a/fa6HnMPCsvzA==",
+      "version": "1.10.72",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.10.72.tgz",
+      "integrity": "sha512-A5mHNNBgO4fI1c/7CZ0bGfVXliy8laP+VaYZ++aWh1YyudoZw4CTCEmLetZRy7AUU3XcfbHa8sAImRi7db+v6Q==",
       "hasInstallScript": true,
       "dependencies": {
         "@apollo/client": "^3.5.8",
@@ -2057,18 +2057,18 @@
         "@cosmjs/proto-signing": "^0.30.1",
         "@cosmjs/stargate": "^0.30.1",
         "@ethersproject/bytes": "^5.7.0",
-        "@injectivelabs/core-proto-ts": "^0.0.12",
-        "@injectivelabs/exceptions": "^1.10.5",
+        "@injectivelabs/core-proto-ts": "^0.0.14",
+        "@injectivelabs/exceptions": "^1.10.12",
         "@injectivelabs/grpc-web": "^0.0.1",
         "@injectivelabs/grpc-web-node-http-transport": "^0.0.2",
         "@injectivelabs/grpc-web-react-native-transport": "^0.0.2",
         "@injectivelabs/indexer-proto-ts": "1.10.8-rc.4",
-        "@injectivelabs/mito-proto-ts": "1.0.4",
-        "@injectivelabs/networks": "^1.10.7",
-        "@injectivelabs/test-utils": "^1.10.2",
-        "@injectivelabs/token-metadata": "^1.10.25",
-        "@injectivelabs/ts-types": "^1.10.4",
-        "@injectivelabs/utils": "^1.10.5",
+        "@injectivelabs/mito-proto-ts": "1.0.9",
+        "@injectivelabs/networks": "^1.10.12",
+        "@injectivelabs/test-utils": "^1.10.12",
+        "@injectivelabs/token-metadata": "^1.10.42",
+        "@injectivelabs/ts-types": "^1.10.12",
+        "@injectivelabs/utils": "^1.10.12",
         "@metamask/eth-sig-util": "^4.0.0",
         "axios": "^0.27.2",
         "bech32": "^2.0.0",
@@ -2266,9 +2266,9 @@
       }
     },
     "node_modules/@injectivelabs/test-utils": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/test-utils/-/test-utils-1.10.2.tgz",
-      "integrity": "sha512-B84qmz4ABxynSiNefUqGbR6ZQOciGJTUv7CSEYN9oRLNZoRCE+jsCVTh9SSqSKF4ZD84llAnyISYWweStW7ifw==",
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/test-utils/-/test-utils-1.11.0.tgz",
+      "integrity": "sha512-/KIPGeLFsjITs43yQG++SoOtDExZr+Pa3JVYIZEIMFUVG8a7z9Vi5m6a1kbowvozZbLG5KHuuUXF2SdfKSxznQ==",
       "hasInstallScript": true,
       "dependencies": {
         "axios": "^0.21.1",
@@ -2288,15 +2288,15 @@
       }
     },
     "node_modules/@injectivelabs/token-metadata": {
-      "version": "1.10.25",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/token-metadata/-/token-metadata-1.10.25.tgz",
-      "integrity": "sha512-irMqhjyovmlYwFquNCWcFfbk16T8cmXT+tnTQsi0G2+YXqUlJJF0dnELvLeYDNROwM2EEJEWvl/4V5DWHKLd7w==",
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/token-metadata/-/token-metadata-1.11.0.tgz",
+      "integrity": "sha512-RzwJvnjDX8IwXYTvZDCMQcGxkN/0ZfXUEYTVMB0WMU0bRH7cV7WJ6Z9UDOijAehrJHu/fByDz2DuEOcktbwoIw==",
       "hasInstallScript": true,
       "dependencies": {
-        "@injectivelabs/exceptions": "^1.10.5",
-        "@injectivelabs/networks": "^1.10.7",
-        "@injectivelabs/ts-types": "^1.10.4",
-        "@injectivelabs/utils": "^1.10.5",
+        "@injectivelabs/exceptions": "^1.11.0",
+        "@injectivelabs/networks": "^1.11.0",
+        "@injectivelabs/ts-types": "^1.11.0",
+        "@injectivelabs/utils": "^1.11.0",
         "@types/lodash.values": "^4.3.6",
         "copyfiles": "^2.4.1",
         "jsonschema": "^1.4.0",
@@ -2306,10 +2306,48 @@
         "shx": "^0.3.2"
       }
     },
+    "node_modules/@injectivelabs/token-metadata/node_modules/@injectivelabs/networks": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.11.0.tgz",
+      "integrity": "sha512-0dtO/zZ8AzsxGInEWZ7tpOA0Q++M3FhAFxOWzhYC39ZeJlwHhEcYmvmhrGG5gRdus29XfFysRlaz3hyT3XH1Jg==",
+      "hasInstallScript": true,
+      "dependencies": {
+        "@injectivelabs/exceptions": "^1.11.0",
+        "@injectivelabs/ts-types": "^1.11.0",
+        "@injectivelabs/utils": "^1.11.0",
+        "link-module-alias": "^1.2.0",
+        "shx": "^0.3.2"
+      }
+    },
+    "node_modules/@injectivelabs/token-metadata/node_modules/@injectivelabs/utils": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.11.0.tgz",
+      "integrity": "sha512-KnUmt4vIvoBz6F3mQomy4GeTkpcHMYwju2AgiqzARrrqgF/2p1ZHfKBpr1ksj/jkl5X+irh3JVfbd/dFjwKi1g==",
+      "hasInstallScript": true,
+      "dependencies": {
+        "@injectivelabs/exceptions": "^1.11.0",
+        "@injectivelabs/ts-types": "^1.11.0",
+        "axios": "^0.21.1",
+        "bignumber.js": "^9.0.1",
+        "http-status-codes": "^2.2.0",
+        "link-module-alias": "^1.2.0",
+        "shx": "^0.3.2",
+        "snakecase-keys": "^5.1.2",
+        "store2": "^2.12.0"
+      }
+    },
+    "node_modules/@injectivelabs/token-metadata/node_modules/axios": {
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+      "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+      "dependencies": {
+        "follow-redirects": "^1.14.0"
+      }
+    },
     "node_modules/@injectivelabs/ts-types": {
-      "version": "1.10.4",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.10.4.tgz",
-      "integrity": "sha512-NvC1xEG/qiRF36mtwM4fr12kwg8UFduQBQ/MQsM8yp1QRH+Qtq/My1j0AGcOWpMZ0tVONhWvUvr+t7Yih7ciAg==",
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.11.0.tgz",
+      "integrity": "sha512-3ZVRW1xMe3RHOxFblRC0LgQcU/rpxgZQZ+sISyRKFGcS/m2ApkdmcPvjMgd5TQe9AXW/6nnvmul3mST8iAaUJg==",
       "hasInstallScript": true,
       "dependencies": {
         "link-module-alias": "^1.2.0",
@@ -2317,13 +2355,13 @@
       }
     },
     "node_modules/@injectivelabs/utils": {
-      "version": "1.10.5",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.10.5.tgz",
-      "integrity": "sha512-9t+9xOh8wQWs/kuUrfWjGAJMVbtgwu20AWdDQl5qeoNxstE7uKTM0hJWCn+OhF5WYloZH7kwfqEUSNZ84G/VpA==",
+      "version": "1.10.12",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.10.12.tgz",
+      "integrity": "sha512-c8al79nxIJgV1cBAdW2TPDGldj/8gm5k0h5TIN/AJs8/AeIjpTwwVGfLY3QvPOpRsxuQ9CjBkTXrAcSL1wwkcw==",
       "hasInstallScript": true,
       "dependencies": {
-        "@injectivelabs/exceptions": "^1.10.5",
-        "@injectivelabs/ts-types": "^1.10.4",
+        "@injectivelabs/exceptions": "^1.10.12",
+        "@injectivelabs/ts-types": "^1.10.12",
         "axios": "^0.21.1",
         "bignumber.js": "^9.0.1",
         "http-status-codes": "^2.2.0",
@@ -8453,16 +8491,16 @@
       "requires": {}
     },
     "@certusone/wormhole-sdk": {
-      "version": "0.9.16",
-      "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.9.16.tgz",
-      "integrity": "sha512-UFcGvMW6yku0Qz4hyFw0H4IKKlUJ2VHrHo0PnSUOfbBf7RfXHKPE9VxsVeCKILbhBzBmECVVP4xF7WlrBBn8/Q==",
+      "version": "0.9.18",
+      "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.9.18.tgz",
+      "integrity": "sha512-0YtrdZmjfiUHL78Yr4FA59ywb+pIevbID/TJpJTp/EKWqm/v+9PS4YBMBEtjpDZR/PSqe6hB8MasF38fUjMGtQ==",
       "requires": {
         "@certusone/wormhole-sdk-proto-web": "0.0.6",
         "@certusone/wormhole-sdk-wasm": "^0.0.1",
         "@coral-xyz/borsh": "0.2.6",
-        "@injectivelabs/networks": "1.10.7",
-        "@injectivelabs/sdk-ts": "1.10.47",
-        "@injectivelabs/utils": "1.10.5",
+        "@injectivelabs/networks": "1.10.12",
+        "@injectivelabs/sdk-ts": "1.10.72",
+        "@injectivelabs/utils": "1.10.12",
         "@mysten/sui.js": "0.32.2",
         "@project-serum/anchor": "^0.25.0",
         "@solana/spl-token": "^0.3.5",
@@ -9326,9 +9364,9 @@
       }
     },
     "@injectivelabs/core-proto-ts": {
-      "version": "0.0.12",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/core-proto-ts/-/core-proto-ts-0.0.12.tgz",
-      "integrity": "sha512-axdL+KWuv4aORIdYqJQy5k9H+bPsi5Y4KWNcYPxrFQ0FAu+sjpvm5PmbIzBSgv/hnIB2cHcLuKvE3BtEa3vJ/w==",
+      "version": "0.0.14",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/core-proto-ts/-/core-proto-ts-0.0.14.tgz",
+      "integrity": "sha512-NZWlgBzgVrXow9IknFQHvcYKX4QkUD25taRigoNYQK8PDn4+VXd9xM5WFUDRhzm2smTCguyl/+MghpEp4oTPWw==",
       "requires": {
         "@injectivelabs/grpc-web": "^0.0.1",
         "google-protobuf": "^3.14.0",
@@ -9363,12 +9401,12 @@
       }
     },
     "@injectivelabs/exceptions": {
-      "version": "1.10.5",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.10.5.tgz",
-      "integrity": "sha512-jeAa5GL3dbe9vXykzu54RP2RETZ6m92XzOTFWb3F0UgB1GtGEDKoMYxN8CJn9RYz3buCPcHxMi/+og6FHu+RaQ==",
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.11.0.tgz",
+      "integrity": "sha512-jZ0N4cP1KCyErNEiCARaKt70E8KMTNa9R4a5FrCERX4cFKPxdbWpoQ8Lqga2jfHAgiFcChRJ5JmaSYclFtKf9w==",
       "requires": {
         "@injectivelabs/grpc-web": "^0.0.1",
-        "@injectivelabs/ts-types": "^1.10.4",
+        "@injectivelabs/ts-types": "^1.11.0",
         "http-status-codes": "^2.2.0",
         "link-module-alias": "^1.2.0",
         "shx": "^0.3.2"
@@ -9432,9 +9470,9 @@
       }
     },
     "@injectivelabs/mito-proto-ts": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/mito-proto-ts/-/mito-proto-ts-1.0.4.tgz",
-      "integrity": "sha512-8raVmZnaXVbpikMTmnc+OtViBPzgyx2ilezUTZFCNcQzZM01lbJlpd0NbF6K5tG76eJ3Wjwj+YpAdRPNuayZ4A==",
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/mito-proto-ts/-/mito-proto-ts-1.0.9.tgz",
+      "integrity": "sha512-+TZMvJ4SHwcn6SFPdqaiQFZdNhjH7hyRFozY15nOTC2utdGij9jEsjz1NsyOejfYDA0s1z5Wm1SgrMYKaVpAmQ==",
       "requires": {
         "@injectivelabs/grpc-web": "^0.0.1",
         "google-protobuf": "^3.14.0",
@@ -9469,39 +9507,39 @@
       }
     },
     "@injectivelabs/networks": {
-      "version": "1.10.7",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.10.7.tgz",
-      "integrity": "sha512-qnU3A7FgTVi4bGEMaSsSIN2wTBhKZfV+3fiwU09aX8ZNcWAilMx8d/mlE1naZFAHs7Kf5hFBxzgeSRZa1GJqiA==",
+      "version": "1.10.12",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.10.12.tgz",
+      "integrity": "sha512-tTHyLls1Nik5QTs/S03qqG2y/ITvNwI8CJOQbMmmsr1CL2CdjJBtzRYn9Dyx2p8XgzRFf9hmlybpe20tq9O3SA==",
       "requires": {
-        "@injectivelabs/exceptions": "^1.10.5",
-        "@injectivelabs/ts-types": "^1.10.4",
-        "@injectivelabs/utils": "^1.10.5",
+        "@injectivelabs/exceptions": "^1.10.12",
+        "@injectivelabs/ts-types": "^1.10.12",
+        "@injectivelabs/utils": "^1.10.12",
         "link-module-alias": "^1.2.0",
         "shx": "^0.3.2"
       }
     },
     "@injectivelabs/sdk-ts": {
-      "version": "1.10.47",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.10.47.tgz",
-      "integrity": "sha512-G11Cdf5iO6is0qWzQRdfiUJLI8IPF4VtD5mVfBwnakrk78syN/Dy492trL7hispDSQaCJaP6a/fa6HnMPCsvzA==",
+      "version": "1.10.72",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.10.72.tgz",
+      "integrity": "sha512-A5mHNNBgO4fI1c/7CZ0bGfVXliy8laP+VaYZ++aWh1YyudoZw4CTCEmLetZRy7AUU3XcfbHa8sAImRi7db+v6Q==",
       "requires": {
         "@apollo/client": "^3.5.8",
         "@cosmjs/amino": "^0.30.1",
         "@cosmjs/proto-signing": "^0.30.1",
         "@cosmjs/stargate": "^0.30.1",
         "@ethersproject/bytes": "^5.7.0",
-        "@injectivelabs/core-proto-ts": "^0.0.12",
-        "@injectivelabs/exceptions": "^1.10.5",
+        "@injectivelabs/core-proto-ts": "^0.0.14",
+        "@injectivelabs/exceptions": "^1.10.12",
         "@injectivelabs/grpc-web": "^0.0.1",
         "@injectivelabs/grpc-web-node-http-transport": "^0.0.2",
         "@injectivelabs/grpc-web-react-native-transport": "^0.0.2",
         "@injectivelabs/indexer-proto-ts": "1.10.8-rc.4",
-        "@injectivelabs/mito-proto-ts": "1.0.4",
-        "@injectivelabs/networks": "^1.10.7",
-        "@injectivelabs/test-utils": "^1.10.2",
-        "@injectivelabs/token-metadata": "^1.10.25",
-        "@injectivelabs/ts-types": "^1.10.4",
-        "@injectivelabs/utils": "^1.10.5",
+        "@injectivelabs/mito-proto-ts": "1.0.9",
+        "@injectivelabs/networks": "^1.10.12",
+        "@injectivelabs/test-utils": "^1.10.12",
+        "@injectivelabs/token-metadata": "^1.10.42",
+        "@injectivelabs/ts-types": "^1.10.12",
+        "@injectivelabs/utils": "^1.10.12",
         "@metamask/eth-sig-util": "^4.0.0",
         "axios": "^0.27.2",
         "bech32": "^2.0.0",
@@ -9702,9 +9740,9 @@
       }
     },
     "@injectivelabs/test-utils": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/test-utils/-/test-utils-1.10.2.tgz",
-      "integrity": "sha512-B84qmz4ABxynSiNefUqGbR6ZQOciGJTUv7CSEYN9oRLNZoRCE+jsCVTh9SSqSKF4ZD84llAnyISYWweStW7ifw==",
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/test-utils/-/test-utils-1.11.0.tgz",
+      "integrity": "sha512-/KIPGeLFsjITs43yQG++SoOtDExZr+Pa3JVYIZEIMFUVG8a7z9Vi5m6a1kbowvozZbLG5KHuuUXF2SdfKSxznQ==",
       "requires": {
         "axios": "^0.21.1",
         "bignumber.js": "^9.0.1",
@@ -9725,14 +9763,14 @@
       }
     },
     "@injectivelabs/token-metadata": {
-      "version": "1.10.25",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/token-metadata/-/token-metadata-1.10.25.tgz",
-      "integrity": "sha512-irMqhjyovmlYwFquNCWcFfbk16T8cmXT+tnTQsi0G2+YXqUlJJF0dnELvLeYDNROwM2EEJEWvl/4V5DWHKLd7w==",
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/token-metadata/-/token-metadata-1.11.0.tgz",
+      "integrity": "sha512-RzwJvnjDX8IwXYTvZDCMQcGxkN/0ZfXUEYTVMB0WMU0bRH7cV7WJ6Z9UDOijAehrJHu/fByDz2DuEOcktbwoIw==",
       "requires": {
-        "@injectivelabs/exceptions": "^1.10.5",
-        "@injectivelabs/networks": "^1.10.7",
-        "@injectivelabs/ts-types": "^1.10.4",
-        "@injectivelabs/utils": "^1.10.5",
+        "@injectivelabs/exceptions": "^1.11.0",
+        "@injectivelabs/networks": "^1.11.0",
+        "@injectivelabs/ts-types": "^1.11.0",
+        "@injectivelabs/utils": "^1.11.0",
         "@types/lodash.values": "^4.3.6",
         "copyfiles": "^2.4.1",
         "jsonschema": "^1.4.0",
@@ -9740,24 +9778,62 @@
         "lodash": "^4.17.21",
         "lodash.values": "^4.3.0",
         "shx": "^0.3.2"
+      },
+      "dependencies": {
+        "@injectivelabs/networks": {
+          "version": "1.11.0",
+          "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.11.0.tgz",
+          "integrity": "sha512-0dtO/zZ8AzsxGInEWZ7tpOA0Q++M3FhAFxOWzhYC39ZeJlwHhEcYmvmhrGG5gRdus29XfFysRlaz3hyT3XH1Jg==",
+          "requires": {
+            "@injectivelabs/exceptions": "^1.11.0",
+            "@injectivelabs/ts-types": "^1.11.0",
+            "@injectivelabs/utils": "^1.11.0",
+            "link-module-alias": "^1.2.0",
+            "shx": "^0.3.2"
+          }
+        },
+        "@injectivelabs/utils": {
+          "version": "1.11.0",
+          "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.11.0.tgz",
+          "integrity": "sha512-KnUmt4vIvoBz6F3mQomy4GeTkpcHMYwju2AgiqzARrrqgF/2p1ZHfKBpr1ksj/jkl5X+irh3JVfbd/dFjwKi1g==",
+          "requires": {
+            "@injectivelabs/exceptions": "^1.11.0",
+            "@injectivelabs/ts-types": "^1.11.0",
+            "axios": "^0.21.1",
+            "bignumber.js": "^9.0.1",
+            "http-status-codes": "^2.2.0",
+            "link-module-alias": "^1.2.0",
+            "shx": "^0.3.2",
+            "snakecase-keys": "^5.1.2",
+            "store2": "^2.12.0"
+          }
+        },
+        "axios": {
+          "version": "0.21.4",
+          "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+          "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+          "requires": {
+            "follow-redirects": "^1.14.0"
+          }
+        }
       }
     },
     "@injectivelabs/ts-types": {
-      "version": "1.10.4",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.10.4.tgz",
-      "integrity": "sha512-NvC1xEG/qiRF36mtwM4fr12kwg8UFduQBQ/MQsM8yp1QRH+Qtq/My1j0AGcOWpMZ0tVONhWvUvr+t7Yih7ciAg==",
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.11.0.tgz",
+      "integrity": "sha512-3ZVRW1xMe3RHOxFblRC0LgQcU/rpxgZQZ+sISyRKFGcS/m2ApkdmcPvjMgd5TQe9AXW/6nnvmul3mST8iAaUJg==",
       "requires": {
         "link-module-alias": "^1.2.0",
         "shx": "^0.3.2"
       }
     },
     "@injectivelabs/utils": {
-      "version": "1.10.5",
-      "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.10.5.tgz",
-      "integrity": "sha512-9t+9xOh8wQWs/kuUrfWjGAJMVbtgwu20AWdDQl5qeoNxstE7uKTM0hJWCn+OhF5WYloZH7kwfqEUSNZ84G/VpA==",
+      "version": "1.10.12",
+      "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.10.12.tgz",
+      "integrity": "sha512-c8al79nxIJgV1cBAdW2TPDGldj/8gm5k0h5TIN/AJs8/AeIjpTwwVGfLY3QvPOpRsxuQ9CjBkTXrAcSL1wwkcw==",
       "requires": {
-        "@injectivelabs/exceptions": "^1.10.5",
-        "@injectivelabs/ts-types": "^1.10.4",
+        "@injectivelabs/exceptions": "^1.10.12",
+        "@injectivelabs/ts-types": "^1.10.12",
         "axios": "^0.21.1",
         "bignumber.js": "^9.0.1",
         "http-status-codes": "^2.2.0",

+ 1 - 1
clients/js/package.json

@@ -29,7 +29,7 @@
   ],
   "dependencies": {
     "@celo-tools/celo-ethers-wrapper": "^0.1.0",
-    "@certusone/wormhole-sdk": "^0.9.16",
+    "@certusone/wormhole-sdk": "^0.9.18",
     "@cosmjs/encoding": "^0.26.2",
     "@injectivelabs/networks": "^1.10.7",
     "@injectivelabs/sdk-ts": "^1.10.47",

+ 64 - 0
clients/js/src/aptos.ts

@@ -9,6 +9,8 @@ import { sha3_256 } from "js-sha3";
 import { NETWORKS } from "./consts";
 import { Network } from "./utils";
 import { Payload, impossible } from "./vaa";
+import { CHAINS, ensureHexPrefix } from "@certusone/wormhole-sdk";
+import { TokenBridgeState } from "@certusone/wormhole-sdk/lib/esm/aptos/types";
 
 export async function execute_aptos(
   payload: Payload,
@@ -335,3 +337,65 @@ function hex(x: string): Buffer {
     "hex"
   );
 }
+
+export async function queryRegistrationsAptos(
+  network: Network,
+  module: "Core" | "NFTBridge" | "TokenBridge"
+): Promise<Object> {
+  const n = NETWORKS[network]["aptos"];
+  const client = new AptosClient(n.rpc);
+  const contracts = CONTRACTS[network]["aptos"];
+  let stateObjectId: string | undefined;
+
+  switch (module) {
+    case "TokenBridge":
+      stateObjectId = contracts.token_bridge;
+      if (stateObjectId === undefined) {
+        throw Error(`Unknown token bridge contract on ${network} for Aptos`);
+      }
+      break;
+    default:
+      throw new Error(`Invalid module: ${module}`);
+  }
+
+  stateObjectId = ensureHexPrefix(stateObjectId);
+  const state = (
+    await client.getAccountResource(
+      stateObjectId,
+      `${stateObjectId}::state::State`
+    )
+  ).data as TokenBridgeState;
+
+  const handle = state.registered_emitters.handle;
+
+  // Query the bridge registration for all the chains in parallel.
+  const registrations: string[][] = await Promise.all(
+    Object.entries(CHAINS)
+      .filter(([cname, _]) => cname !== "aptos" && cname !== "unset")
+      .map(async ([cname, cid]) => [
+        cname,
+        await (async () => {
+          let result = null;
+          try {
+            result = await client.getTableItem(handle, {
+              key_type: "u64",
+              value_type: "vector<u8>",
+              key: cid.toString(),
+            });
+          } catch {
+            // Not logging anything because a chain not registered returns an error.
+          }
+
+          return result;
+        })(),
+      ])
+  );
+
+  const results: { [key: string]: string } = {};
+  for (let [cname, queryResponse] of registrations) {
+    if (queryResponse) {
+      results[cname] = queryResponse;
+    }
+  }
+  return results;
+}

+ 79 - 0
clients/js/src/chains/sei/registrations.ts

@@ -0,0 +1,79 @@
+import { getCosmWasmClient } from "@sei-js/core";
+import {
+  ChainName,
+  CHAINS,
+  CONTRACTS,
+} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
+import { NETWORKS } from "../../consts/networks";
+import { Network } from "../../utils";
+
+export async function queryRegistrationsSei(
+  network: Network,
+  module: "Core" | "NFTBridge" | "TokenBridge"
+): Promise<Object> {
+  const chain = "sei" as ChainName;
+  const n = NETWORKS[network][chain];
+  const contracts = CONTRACTS[network][chain];
+
+  let target_contract: string | undefined;
+
+  switch (module) {
+    case "TokenBridge":
+      target_contract = contracts.token_bridge;
+      break;
+    case "NFTBridge":
+      target_contract = contracts.nft_bridge;
+      break;
+    default:
+      throw new Error(`Invalid module: ${module}`);
+  }
+
+  if (!target_contract) {
+    throw new Error(`Contract for ${module} on ${network} does not exist`);
+  }
+
+  if (n.rpc === undefined) {
+    throw new Error(`RPC for ${module} on ${network} does not exist`);
+  }
+
+  // Create a CosmWasmClient
+  const client = await getCosmWasmClient(n.rpc);
+
+  // Query the bridge registration for all the chains in parallel.
+  const registrations = await Promise.all(
+    Object.entries(CHAINS)
+      .filter(([c_name, _]) => c_name !== chain && c_name !== "unset")
+      .map(async ([c_name, c_id]) => [
+        c_name,
+        await (async () => {
+          let query_msg = {
+            chain_registration: {
+              chain: c_id,
+            },
+          };
+
+          let result = null;
+          try {
+            result = await client.queryContractSmart(
+              target_contract as string,
+              query_msg
+            );
+          } catch {
+            // Not logging anything because a chain not registered returns an error.
+          }
+
+          return result;
+        })(),
+      ])
+  );
+
+  const results: { [key: string]: string } = {};
+  for (let [c_name, queryResponse] of registrations) {
+    if (queryResponse) {
+      results[c_name] = Buffer.from(queryResponse.address, "base64").toString(
+        "hex"
+      );
+    }
+  }
+  return results;
+}

+ 57 - 0
clients/js/src/chains/sui/registrations.ts

@@ -0,0 +1,57 @@
+import { getObjectFields } from "@certusone/wormhole-sdk/lib/esm/sui";
+import {
+  CHAIN_ID_TO_NAME,
+  CONTRACTS,
+} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
+import { NETWORKS } from "../../consts/networks";
+import { Network } from "../../utils";
+import { getProvider } from "./utils";
+import { ChainId } from "@certusone/wormhole-sdk";
+
+export async function queryRegistrationsSui(
+  network: Network,
+  module: "Core" | "NFTBridge" | "TokenBridge"
+): Promise<Object> {
+  const n = NETWORKS[network]["sui"];
+  const provider = getProvider(network, n.rpc);
+  const contracts = CONTRACTS[network]["sui"];
+  let state_object_id: string;
+
+  switch (module) {
+    case "TokenBridge":
+      state_object_id = contracts.token_bridge;
+      if (state_object_id === undefined) {
+        throw Error(`Unknown token bridge contract on ${network} for Sui`);
+      }
+      break;
+    default:
+      throw new Error(`Invalid module: ${module}`);
+  }
+
+  const state = await getObjectFields(provider, state_object_id);
+  const emitterRegistryId = state!.emitter_registry.fields.id.id;
+
+  // TODO: handle pagination
+  //   - recursive: https://github.com/wormhole-foundation/wormhole/blob/7608b2b740df5d4c2551daaf4d620eac81c07790/sdk/js/src/sui/utils.ts#L175
+  //   - iterative: https://github.com/wormhole-foundation/wormhole/blob/7608b2b740df5d4c2551daaf4d620eac81c07790/sdk/js/src/sui/utils.ts#L199
+  const emitterRegistry = await provider.getDynamicFields({
+    parentId: emitterRegistryId,
+  });
+
+  const results: { [key: string]: string } = {};
+  for (let idx = 0; idx < emitterRegistry.data.length; idx++) {
+    const chainId = emitterRegistry.data[idx].name.value as ChainId;
+    for (const { objectId } of emitterRegistry.data.slice(idx, idx + 1)) {
+      const emitter = (await provider.getObject({
+        id: objectId,
+        options: { showContent: true },
+      })) as any;
+      const emitterAddress: Uint8Array =
+        emitter.data?.content?.fields.value.fields.value.fields.data;
+      const emitterAddrStr = Buffer.from(emitterAddress).toString("hex");
+      results[CHAIN_ID_TO_NAME[chainId]] = emitterAddrStr;
+    }
+  }
+
+  return results;
+}

+ 2 - 0
clients/js/src/cmds/info/index.ts

@@ -3,6 +3,7 @@ import * as chainId from "./chainId";
 import * as contract from "./contract";
 import * as emitter from "./emitter";
 import * as origin from "./origin";
+import * as registrations from "./registrations";
 import * as rpc from "./rpc";
 import * as wrapped from "./wrapped";
 
@@ -15,6 +16,7 @@ export const builder = (y: typeof yargs) =>
     .command(contract)
     .command(emitter)
     .command(origin)
+    .command(registrations)
     .command(rpc)
     .command(wrapped);
 export const handler = () => {};

+ 164 - 0
clients/js/src/cmds/info/registrations.ts

@@ -0,0 +1,164 @@
+// The registration command queries the TokenBridge or NFTBridge for all bridges registered with it. By default,
+// it prints out the results. Optionally, you can specify --verify to have it verify the registrations against what
+// is defined in the consts.ts file in the SDK (to verify that all chains // are properly registered.)
+
+import yargs from "yargs";
+import {
+  assertChain,
+  ChainName,
+  CHAINS,
+  Contracts,
+  CONTRACTS,
+  isEVMChain,
+  isTerraChain,
+} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
+import { getEmitterAddress } from "../../emitter";
+
+export const command = "registrations <network> <chain> <module>";
+export const desc = "Print chain registrations";
+export const builder = (y: typeof yargs) => {
+  return y
+    .positional("network", {
+      describe: "network",
+      choices: ["mainnet", "testnet", "devnet"],
+      demandOption: true,
+    } as const)
+    .positional("chain", {
+      describe: "Chain to query",
+      choices: Object.keys(CHAINS) as ChainName[],
+      demandOption: true,
+    } as const)
+    .positional("module", {
+      describe: "Module to query (TokenBridge or NFTBridge)",
+      type: "string",
+      choices: ["NFTBridge", "TokenBridge"],
+      demandOption: true,
+    })
+    .option("verify", {
+      alias: "v",
+      describe: "Verify the results against the const file",
+      type: "boolean",
+      default: false,
+      demandOption: false,
+    });
+};
+export const handler = async (
+  argv: Awaited<ReturnType<typeof builder>["argv"]>
+) => {
+  assertChain(argv.chain);
+  const chain = argv.chain;
+  const network = argv.network.toUpperCase();
+  if (network !== "MAINNET" && network !== "TESTNET" && network !== "DEVNET") {
+    throw Error(`Unknown network: ${network}`);
+  }
+  const module = argv.module;
+  if (module !== "TokenBridge" && module !== "NFTBridge") {
+    throw Error(`Module must be TokenBridge or NFTBridge`);
+  }
+  let results: object;
+  if (chain === "solana") {
+    const solana = require("../../solana");
+    results = await solana.queryRegistrationsSolana(network, module);
+  } else if (isEVMChain(chain)) {
+    const evm = require("../../evm");
+    results = await evm.queryRegistrationsEvm(network, chain, module);
+  } else if (isTerraChain(chain) || chain === "xpla") {
+    const terra = require("../../terra");
+    results = await terra.queryRegistrationsTerra(network, chain, module);
+  } else if (chain === "injective") {
+    const injective = require("../../injective");
+    results = await injective.queryRegistrationsInjective(network, module);
+  } else if (chain === "sei") {
+    const sei = require("../../chains/sei/registrations");
+    results = await sei.queryRegistrationsSei(network, module);
+  } else if (chain === "sui") {
+    const sui = require("../../chains/sui/registrations");
+    results = await sui.queryRegistrationsSui(network, module);
+  } else if (chain === "aptos") {
+    const aptos = require("../../aptos");
+    results = await aptos.queryRegistrationsAptos(network, module);
+  } else {
+    throw Error(`Command not supported for chain ${chain}`);
+  }
+  if (argv["verify"]) {
+    verifyRegistrations(network, chain as string, module, results);
+  } else {
+    console.log(results);
+  }
+};
+
+// verifyRegistrations takes the results returned above and verifies them against the expected values in the consts file.
+async function verifyRegistrations(
+  network: "MAINNET" | "TESTNET" | "DEVNET",
+  chain: string,
+  module: "NFTBridge" | "TokenBridge",
+  input: Object
+) {
+  let mismatchFound = false;
+
+  // Put the input in a map so we can do lookups.
+  let inputMap = new Map<string, string>();
+  for (const [cname, reg] of Object.entries(input)) {
+    inputMap.set(cname as string, reg as string);
+  }
+
+  // Loop over the chains and make sure everything is in our input, and the values match.
+  const results: { [key: string]: string } = {};
+  for (const chainStr in CHAINS) {
+    const thisChain = chainStr as ChainName;
+    if (thisChain === "unset" || thisChain === chain) {
+      continue;
+    }
+    const contracts: Contracts = CONTRACTS[network][thisChain];
+
+    let expectedAddr: string | undefined;
+    if (module === "TokenBridge") {
+      expectedAddr = contracts.token_bridge;
+    } else {
+      expectedAddr = contracts.nft_bridge;
+    }
+
+    if (expectedAddr !== undefined) {
+      expectedAddr = await getEmitterAddress(
+        thisChain as ChainName,
+        expectedAddr
+      );
+      if (!expectedAddr.startsWith("0x")) {
+        expectedAddr = "0x" + expectedAddr;
+      }
+    }
+
+    let actualAddr = inputMap.get(thisChain as string);
+    if (actualAddr !== undefined && !actualAddr.startsWith("0x")) {
+      actualAddr = "0x" + actualAddr;
+    }
+    if (expectedAddr !== undefined) {
+      if (
+        actualAddr === undefined ||
+        actualAddr ===
+          "0x0000000000000000000000000000000000000000000000000000000000000000"
+      ) {
+        results[thisChain] = "Missing " + expectedAddr;
+        mismatchFound = true;
+      } else if (actualAddr !== expectedAddr) {
+        results[thisChain] =
+          "Expected " + expectedAddr + ", found " + actualAddr;
+        mismatchFound = true;
+      }
+    } else if (
+      actualAddr !== undefined &&
+      actualAddr !==
+        "0x0000000000000000000000000000000000000000000000000000000000000000"
+    ) {
+      results[thisChain] = "Expected null , found " + actualAddr;
+      mismatchFound = true;
+    }
+  }
+
+  if (mismatchFound) {
+    console.log(`Mismatches found on  ${chain} ${network}!`);
+    console.log(results);
+  } else {
+    console.log(`Verification of ${chain} ${network} succeeded!`);
+  }
+}

+ 26 - 33
clients/js/src/cmds/submit.ts

@@ -135,13 +135,13 @@ export const handler = async (
 };
 
 async function executeSubmit(
-  vaa_hex: string,
-  parsed_vaa: VAA<Payload>,
+  vaaHex: string,
+  parsedVaa: VAA<Payload>,
   buf: Buffer,
   network: Network,
   chain: ChainName,
   rpc: string | undefined,
-  contract_address: string | undefined
+  contractAddress: string | undefined
 ) {
   if (chain === "unset") {
     throw Error(
@@ -149,43 +149,37 @@ async function executeSubmit(
     );
   } else if (isEVMChain(chain)) {
     await execute_evm(
-      parsed_vaa.payload,
+      parsedVaa.payload,
       buf,
       network,
       chain,
-      contract_address,
+      contractAddress,
       rpc
     );
   } else if (isTerraChain(chain)) {
-    await execute_terra(parsed_vaa.payload, buf, network, chain);
+    await execute_terra(parsedVaa.payload, buf, network, chain);
   } else if (chain === "solana" || chain === "pythnet") {
-    await execute_solana(parsed_vaa, buf, network, chain);
+    await execute_solana(parsedVaa, buf, network, chain);
   } else if (chain === "algorand") {
     await execute_algorand(
-      parsed_vaa.payload,
-      new Uint8Array(Buffer.from(vaa_hex, "hex")),
+      parsedVaa.payload,
+      new Uint8Array(Buffer.from(vaaHex, "hex")),
       network
     );
   } else if (chain === "near") {
-    await execute_near(parsed_vaa.payload, vaa_hex, network);
+    await execute_near(parsedVaa.payload, vaaHex, network);
   } else if (chain === "injective") {
-    await execute_injective(parsed_vaa.payload, buf, network);
+    await execute_injective(parsedVaa.payload, buf, network);
   } else if (chain === "xpla") {
-    await execute_xpla(parsed_vaa.payload, buf, network);
+    await execute_xpla(parsedVaa.payload, buf, network);
   } else if (chain === "sei") {
-    await submitSei(parsed_vaa.payload, buf, network);
+    await submitSei(parsedVaa.payload, buf, network);
   } else if (chain === "osmosis") {
     throw Error("OSMOSIS is not supported yet");
   } else if (chain === "sui") {
-    await submitSui(parsed_vaa.payload, buf, network, rpc);
+    await submitSui(parsedVaa.payload, buf, network, rpc);
   } else if (chain === "aptos") {
-    await execute_aptos(
-      parsed_vaa.payload,
-      buf,
-      network,
-      contract_address,
-      rpc
-    );
+    await execute_aptos(parsedVaa.payload, buf, network, contractAddress, rpc);
   } else if (chain === "wormchain") {
     throw Error("Wormchain is not supported yet");
   } else if (chain === "btc") {
@@ -198,19 +192,19 @@ async function executeSubmit(
 }
 
 async function submitToAll(
-  vaa_hex: string,
-  parsed_vaa: VAA<Payload>,
+  vaaHex: string,
+  parsedVaa: VAA<Payload>,
   buf: Buffer,
   network: Network
 ) {
   let skip_chain: ChainName = "unset";
-  if (parsed_vaa.payload.type === "RegisterChain") {
-    skip_chain = toChainName(parsed_vaa.payload.emitterChain as ChainId);
-  } else if (parsed_vaa.payload.type === "AttestMeta") {
-    skip_chain = toChainName(parsed_vaa.payload.tokenChain as ChainId);
+  if (parsedVaa.payload.type === "RegisterChain") {
+    skip_chain = toChainName(parsedVaa.payload.emitterChain as ChainId);
+  } else if (parsedVaa.payload.type === "AttestMeta") {
+    skip_chain = toChainName(parsedVaa.payload.tokenChain as ChainId);
   } else {
     throw Error(
-      `Invalid VAA payload type (${parsed_vaa.payload.type}), only "RegisterChain" and "AttestMeta" are supported with --all-chains`
+      `Invalid VAA payload type (${parsedVaa.payload.type}), only "RegisterChain" and "AttestMeta" are supported with --all-chains`
     );
   }
 
@@ -236,9 +230,8 @@ async function submitToAll(
       return true;
     }
     if (
-      (parsed_vaa.payload.module === "TokenBridge" &&
-        !contracts.token_bridge) ||
-      (parsed_vaa.payload.module === "NFTBridge" && !contracts.nft_bridge)
+      (parsedVaa.payload.module === "TokenBridge" && !contracts.token_bridge) ||
+      (parsedVaa.payload.module === "NFTBridge" && !contracts.nft_bridge)
     ) {
       console.log(`Skipping ${chain} because the contract is not defined`);
       continue;
@@ -247,8 +240,8 @@ async function submitToAll(
     console.log(`Submitting VAA to ${chain} ${network}`);
     try {
       await executeSubmit(
-        vaa_hex,
-        parsed_vaa,
+        vaaHex,
+        parsedVaa,
         buf,
         network,
         chain,

+ 2 - 2
clients/js/src/emitter.ts

@@ -52,11 +52,11 @@ export async function getEmitterAddress(
       addr = "ccceeb29348f71bdd22ffef43a2a19c1f5b5e17c5cca5411529120182672ade5";
     } else if (
       addr ===
-      "0x32422cb2f929b6a4e3f81b4791ea11ac2af896b310f3d9442aa1fe924ce0bab4"
+      "0x6fb10cdb7aa299e9a4308752dadecb049ff55a892de92992a1edbd7912b3d6da"
     ) {
       // Testnet TokenBridge
       addr =
-        "0xb22cd218bb63da447ac2704c1cc72727df6b5e981ee17a22176fd7b84c114610";
+        "0x40440411a170b4842ae7dee4f4a7b7a58bc0a98566e998850a7bb87bf5dc05b9";
     } else {
       throw Error(`Unsupported Sui address: ${addr}`);
     }

+ 51 - 0
clients/js/src/evm.ts

@@ -721,3 +721,54 @@ const maybeUnsupported = async <T>(
 
 const isUnsupportedError = (e: any): e is { reason: string } =>
   e && typeof e === "object" && "reason" in e && e.reason === "unsupported";
+
+export async function queryRegistrationsEvm(
+  network: Network,
+  chain: EVMChainName,
+  module: "Core" | "NFTBridge" | "TokenBridge"
+): Promise<Object> {
+  const n = NETWORKS[network][chain];
+  const contracts = CONTRACTS[network][chain];
+
+  let targetContract: string | undefined;
+  let contract: any;
+
+  const provider = new ethers.providers.JsonRpcProvider(n.rpc);
+
+  switch (module) {
+    case "TokenBridge":
+      targetContract = contracts.token_bridge;
+      if (targetContract === undefined) {
+        throw Error(`Unknown token bridge contract on ${network} for ${chain}`);
+      }
+      contract = BridgeImplementation__factory.connect(
+        targetContract,
+        provider
+      );
+      break;
+    case "NFTBridge":
+      targetContract = contracts.nft_bridge;
+      if (targetContract === undefined) {
+        throw Error(`Unknown NFT bridge contract on ${network} for ${chain}`);
+      }
+      contract = NFTBridgeImplementation__factory.connect(
+        targetContract,
+        provider
+      );
+      break;
+    default:
+      throw new Error(`Invalid module: ${module}`);
+  }
+
+  const registrations: string[][] = await Promise.all(
+    Object.entries(CHAINS)
+      .filter(([cname, _]) => cname !== chain && cname !== "unset")
+      .map(async ([cname, cid]) => [cname, await contract.bridgeContracts(cid)])
+  );
+
+  const results: { [key: string]: string } = {};
+  for (let [cname, c] of registrations) {
+    results[cname] = c;
+  }
+  return results;
+}

+ 75 - 1
clients/js/src/injective.ts

@@ -1,9 +1,13 @@
-import { CONTRACTS } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
+import {
+  CHAINS,
+  CONTRACTS,
+} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
 import {
   getNetworkInfo,
   Network as InjectiveNetwork,
 } from "@injectivelabs/networks";
 import {
+  ChainGrpcWasmApi,
   ChainRestAuthApi,
   createTransaction,
   MsgExecuteContractCompat,
@@ -203,3 +207,73 @@ export async function execute_injective(
     );
   }
 }
+
+export async function queryRegistrationsInjective(
+  network: Network,
+  module: "Core" | "NFTBridge" | "TokenBridge"
+) {
+  const chain = "injective";
+  const n = NETWORKS[network][chain];
+  const contracts = CONTRACTS[network][chain];
+
+  let targetContract: string | undefined;
+
+  switch (module) {
+    case "TokenBridge":
+      targetContract = contracts.token_bridge;
+      break;
+    case "NFTBridge":
+      targetContract = contracts.nft_bridge;
+      break;
+    default:
+      throw new Error(`Invalid module: ${module}`);
+  }
+
+  if (targetContract === undefined) {
+    throw new Error(`Contract for ${module} on ${network} does not exist`);
+  }
+
+  if (n === undefined || n.rpc === undefined) {
+    throw new Error(`RPC for ${module} on ${network} does not exist`);
+  }
+
+  const client = new ChainGrpcWasmApi(n.rpc);
+
+  // Query the bridge registration for all the chains in parallel.
+  const registrations: (any | null)[][] = await Promise.all(
+    Object.entries(CHAINS)
+      .filter(([cname, _]) => cname !== chain && cname !== "unset")
+      .map(async ([cname, cid]) => [
+        cname,
+        await (async () => {
+          let query_msg = {
+            chain_registration: {
+              chain: cid,
+            },
+          };
+
+          let result = null;
+          try {
+            result = await client.fetchSmartContractState(
+              targetContract as string,
+              Buffer.from(JSON.stringify(query_msg)).toString("base64")
+            );
+          } catch {
+            // Not logging anything because a chain not registered returns an error.
+          }
+
+          return result;
+        })(),
+      ])
+  );
+
+  const results: { [key: string]: string } = {};
+  for (let [cname, queryResponse] of registrations) {
+    if (queryResponse) {
+      results[cname] = Buffer.from(queryResponse.address, "base64").toString(
+        "hex"
+      );
+    }
+  }
+  console.log(results);
+}

+ 88 - 0
clients/js/src/solana.ts

@@ -9,6 +9,8 @@ import {
   createCreateWrappedInstruction,
   createRegisterChainInstruction as createTokenBridgeRegisterChainInstruction,
   createUpgradeContractInstruction as createTokenBridgeUpgradeContractInstruction,
+  deriveEndpointKey,
+  getEndpointRegistration,
 } from "@certusone/wormhole-sdk/lib/esm/solana/tokenBridge";
 import {
   createUpgradeGuardianSetInstruction,
@@ -23,6 +25,9 @@ import * as web3s from "@solana/web3.js";
 import base58 from "bs58";
 import { NETWORKS } from "./consts";
 import { Payload, VAA, impossible } from "./vaa";
+import { ChainName, hexToUint8Array } from "@certusone/wormhole-sdk";
+import { getEmitterAddress } from "./emitter";
+import { Network } from "./utils";
 
 export async function execute_solana(
   v: VAA<Payload>,
@@ -212,3 +217,86 @@ export async function execute_solana(
 
 const setupConnection = (rpc: string): web3s.Connection =>
   new web3s.Connection(rpc, "confirmed");
+
+// queryRegistrationsSolana queries the bridge contract for chain registrations.
+// Solana does not support querying to see "What address is chain X registered for?" Instead
+// we have to ask "Is chain X registered with address Y?" Therefore, we loop through all of the
+// chains and query to see if the latest address defined in the const file is registered.
+export async function queryRegistrationsSolana(
+  network: Network,
+  module: "Core" | "NFTBridge" | "TokenBridge"
+): Promise<Object> {
+  const chain = "solana" as ChainName;
+  const n = NETWORKS[network][chain];
+  const contracts = CONTRACTS[network][chain];
+
+  let targetAddress: string | undefined;
+
+  switch (module) {
+    case "TokenBridge":
+      targetAddress = contracts.token_bridge;
+      break;
+    case "NFTBridge":
+      targetAddress = contracts.nft_bridge;
+      break;
+    default:
+      throw new Error(`Invalid module: ${module}`);
+  }
+
+  if (!targetAddress) {
+    throw new Error(`Contract for ${module} on ${network} does not exist`);
+  }
+
+  if (n === undefined || n.rpc === undefined) {
+    throw new Error(`RPC for ${module} on ${network} does not exist`);
+  }
+
+  const connection = setupConnection(n.rpc);
+  const programId = new web3s.PublicKey(targetAddress);
+
+  // Query the bridge registration for all the chains in parallel.
+  const registrations: (string | null)[][] = await Promise.all(
+    Object.entries(CHAINS)
+      .filter(([cname, _]) => cname !== chain && cname !== "unset")
+      .map(async ([cstr, cid]) => [
+        cstr,
+        await (async () => {
+          let cname = cstr as ChainName;
+          let addr: string | undefined;
+          if (module === "TokenBridge") {
+            addr = CONTRACTS[network][cname].token_bridge;
+          } else {
+            addr = CONTRACTS[network][cname].nft_bridge;
+          }
+          if (addr === undefined) {
+            return null;
+          }
+          let emitter_addr = await getEmitterAddress(cname as ChainName, addr);
+
+          const endpoint = deriveEndpointKey(
+            programId,
+            cid,
+            hexToUint8Array(emitter_addr)
+          );
+
+          let result: string | null = null;
+          try {
+            await getEndpointRegistration(connection, endpoint);
+            result = emitter_addr;
+          } catch {
+            // Not logging anything because a chain not registered returns an error.
+          }
+
+          return result as string;
+        })(),
+      ])
+  );
+
+  const results: { [key: string]: string } = {};
+  for (let [cname, queryResponse] of registrations) {
+    if (cname && queryResponse) {
+      results[cname] = queryResponse;
+    }
+  }
+  return results;
+}

+ 80 - 0
clients/js/src/terra.ts

@@ -1,4 +1,5 @@
 import {
+  CHAINS,
   CONTRACTS,
   TerraChainName,
 } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
@@ -183,3 +184,82 @@ export async function execute_terra(
       console.log(`TX hash: ${result.txhash}`);
     });
 }
+
+export async function queryRegistrationsTerra(
+  network: Network,
+  chain: TerraChainName,
+  module: "Core" | "NFTBridge" | "TokenBridge"
+): Promise<Object> {
+  const n = NETWORKS[network][chain];
+  const contracts = CONTRACTS[network][chain];
+
+  let targetContract: string | undefined;
+
+  switch (module) {
+    case "TokenBridge":
+      targetContract = contracts.token_bridge;
+      break;
+    case "NFTBridge":
+      targetContract = contracts.nft_bridge;
+      break;
+    default:
+      throw new Error(`Invalid module: ${module}`);
+  }
+
+  if (targetContract === undefined) {
+    throw new Error(`Contract for ${module} on ${network} does not exist`);
+  }
+
+  if (n === undefined || n.rpc === undefined) {
+    throw new Error(`RPC for ${module} on ${network} does not exist`);
+  }
+
+  if (n === undefined || n.chain_id === undefined) {
+    throw new Error(`Chain id for ${module} on ${network} does not exist`);
+  }
+
+  const client = new LCDClient({
+    URL: n.rpc,
+    chainID: n.chain_id,
+    isClassic: chain === "terra",
+  });
+
+  // Query the bridge registration for all the chains in parallel.
+  const registrations: (string | null)[][] = await Promise.all(
+    Object.entries(CHAINS)
+      .filter(([cname, _]) => cname !== chain && cname !== "unset")
+      .map(async ([cname, cid]) => [
+        cname,
+        await (async () => {
+          let query_msg = {
+            chain_registration: {
+              chain: cid,
+            },
+          };
+
+          let result = null;
+          try {
+            const resp: { address: string } = await client.wasm.contractQuery(
+              targetContract as string,
+              query_msg
+            );
+            if (resp) {
+              result = resp.address;
+            }
+          } catch {
+            // Not logging anything because a chain not registered returns an error.
+          }
+
+          return result;
+        })(),
+      ])
+  );
+
+  const results: { [key: string]: string } = {};
+  for (let [cname, queryResponse] of registrations) {
+    if (cname && queryResponse) {
+      results[cname] = Buffer.from(queryResponse, "base64").toString("hex");
+    }
+  }
+  return results;
+}