diff --git a/package-lock.json b/package-lock.json index 0b548c06..64ef2906 100644 --- a/package-lock.json +++ b/package-lock.json @@ -768,6 +768,14 @@ "case": "^1.6.3" } }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@confio/ics23": { "version": "0.6.8", "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.8.tgz", @@ -777,6 +785,89 @@ "protobufjs": "^6.8.8" } }, + "node_modules/@confio/relayer": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@confio/relayer/-/relayer-0.10.0.tgz", + "integrity": "sha512-/WW5Eyfgylby9u0wz6XakA7yo5hamdWh6pxkOYHPz0ls7ikd7Ld+c2fpRbL0Qg5wZn9+9P+Uhfj4l0pVl3WPgw==", + "dependencies": { + "@cosmjs/cosmwasm-stargate": "^0.31.0", + "@cosmjs/crypto": "^0.31.0", + "@cosmjs/encoding": "^0.31.0", + "@cosmjs/faucet-client": "^0.31.0", + "@cosmjs/math": "^0.31.0", + "@cosmjs/proto-signing": "^0.31.0", + "@cosmjs/stargate": "^0.31.0", + "@cosmjs/stream": "^0.31.0", + "@cosmjs/tendermint-rpc": "^0.31.0", + "@cosmjs/utils": "^0.31.0", + "ajv": "7.1.1", + "axios": "0.21.4", + "commander": "7.1.0", + "cosmjs-types": "^0.8.0", + "fast-safe-stringify": "2.0.4", + "js-yaml": "4.0.0", + "lodash": "4.17.21", + "prom-client": "13.1.0", + "protobufjs": "^6.10.3", + "table": "^6.7.1", + "triple-beam": "1.3.0", + "winston": "3.3.3" + }, + "bin": { + "ibc-relayer": "build/binary/ibc-relayer/index.js", + "ibc-setup": "build/binary/ibc-setup/index.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@confio/relayer/node_modules/ajv": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.1.tgz", + "integrity": "sha512-ga/aqDYnUy/o7vbsRTFhhTsNeXiYb5JWDIcRIeZfwRNCefwjNTVYCGdGSUrEmiu3yDK3vFvNbgJxvrQW4JXrYQ==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@confio/relayer/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/@confio/relayer/node_modules/commander": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz", + "integrity": "sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@confio/relayer/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@confio/relayer/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, "node_modules/@cosmjs/amino": { "version": "0.31.1", "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.31.1.tgz", @@ -830,6 +921,22 @@ "readonly-date": "^1.0.0" } }, + "node_modules/@cosmjs/faucet-client": { + "version": "0.31.3", + "resolved": "https://registry.npmjs.org/@cosmjs/faucet-client/-/faucet-client-0.31.3.tgz", + "integrity": "sha512-gsVD/UD1R2k00iRVcBwXRgTkwzsnapfw8n1eWfc7o44xg0aVG8YL84ntj2YmjC9+NHCp2rmK9xndQeUOFIszOA==", + "dependencies": { + "axios": "^0.21.2" + } + }, + "node_modules/@cosmjs/faucet-client/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/@cosmjs/json-rpc": { "version": "0.31.1", "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.31.1.tgz", @@ -959,6 +1066,16 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -5599,7 +5716,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, "dependencies": { "type-detect": "4.0.8" } @@ -5608,11 +5724,25 @@ "version": "10.0.2", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", - "dev": true, "dependencies": { "@sinonjs/commons": "^2.0.0" } }, + "node_modules/@sinonjs/samsam": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==" + }, "node_modules/@solidity-parser/parser": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", @@ -6702,12 +6832,30 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, + "node_modules/@types/sinon": { + "version": "10.0.20", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.20.tgz", + "integrity": "sha512-2APKKruFNCAZgx3daAyACGzWuJ028VVCUDk6o2rw/Z4PXT0ogwdV4KUegW0MwVs0Zu59auPXbbuBJHF12Sx1Eg==", + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.4.tgz", + "integrity": "sha512-GDV68H0mBSN449sa5HEj51E0wfpVQb8xNSMzxf/PrypMFcLTMwJMOM/cgXiv71Mq5drkOQmUGvL1okOZcu6RrQ==" + }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/triple-beam": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.4.tgz", + "integrity": "sha512-HlJjF3wxV4R2VQkFpKe0YqJLilYNgtRtsqqZtby7RkVsSs+i+vbyzjtUwpFEdUCKcrGzCiEJE7F/0mKjh0sunA==" + }, "node_modules/@types/yargs": { "version": "17.0.24", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", @@ -7304,7 +7452,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -7392,8 +7539,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-back": { "version": "3.1.0", @@ -7600,7 +7746,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, "engines": { "node": ">=8" } @@ -7608,8 +7753,7 @@ "node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "dev": true + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, "node_modules/async-limiter": { "version": "1.0.1", @@ -7982,6 +8126,11 @@ "node": ">=8" } }, + "node_modules/bintrees": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", + "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==" + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -9057,11 +9206,19 @@ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -9069,8 +9226,16 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } }, "node_modules/color-support": { "version": "1.1.3", @@ -9090,6 +9255,15 @@ "node": ">=0.1.90" } }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, "node_modules/columnify": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", @@ -10145,8 +10319,12 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -12233,8 +12411,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-diff": { "version": "1.2.0", @@ -12282,6 +12459,11 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-safe-stringify": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.4.tgz", + "integrity": "sha512-mNlGUdKOeGNleyrmgbKYtbnCr9KZkZXU7eM89JRo8vY10f7Ul1Fbj07hUBW3N4fC0xM+fmfFfa2zM7mIizhpNQ==" + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -12300,6 +12482,11 @@ "bser": "2.1.1" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -12476,6 +12663,11 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", @@ -15326,7 +15518,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, "engines": { "node": ">=8" }, @@ -17495,6 +17686,11 @@ "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", "dev": true }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==" + }, "node_modules/keccak": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", @@ -17546,6 +17742,11 @@ "node": ">=6" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/lerna": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/lerna/-/lerna-6.6.2.tgz", @@ -18599,6 +18800,11 @@ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, "node_modules/lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", @@ -18620,8 +18826,7 @@ "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -18709,6 +18914,22 @@ "node": ">=8" } }, + "node_modules/logform": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", + "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -19837,8 +20058,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/multibase": { "version": "0.6.1", @@ -20149,6 +20369,31 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node_modules/nise": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", + "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==", + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/nise/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/nise/node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dependencies": { + "isarray": "0.0.1" + } + }, "node_modules/node-addon-api": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", @@ -21424,6 +21669,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -22499,6 +22752,17 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "node_modules/prom-client": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.1.0.tgz", + "integrity": "sha512-jT9VccZCWrJWXdyEtQddCDszYsiuWj5T0ekrPszi/WEegj3IZy6Mm09iOOVM86A4IKMWq8hZkT2dD9MaSe+sng==", + "dependencies": { + "tdigest": "^0.1.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/promise": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", @@ -22672,7 +22936,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, "engines": { "node": ">=6" } @@ -23203,7 +23466,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -23449,7 +23711,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -23717,6 +23978,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -24266,6 +24535,79 @@ "node": ">=4" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/sinon": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.0.tgz", + "integrity": "sha512-p4lJiYKBoOEVUxxVIC9H1MM2znG1/c8gud++I2BauJA5hsz7hHsst35eurNWXTusBsIq66FzOQbZ/uMdpvbPIQ==", + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/sinon/node_modules/@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sinon/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -24285,7 +24627,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -24302,7 +24643,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -24317,7 +24657,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -24328,14 +24667,12 @@ "node_modules/slice-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -24912,6 +25249,14 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -24999,7 +25344,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -25008,7 +25352,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -25167,7 +25510,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -25532,7 +25874,6 @@ "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -25581,7 +25922,6 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -25597,7 +25937,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -25605,14 +25944,12 @@ "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/table/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -25685,6 +26022,14 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "devOptional": true }, + "node_modules/tdigest": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", + "integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==", + "dependencies": { + "bintrees": "1.0.2" + } + }, "node_modules/temp-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", @@ -25781,6 +26126,11 @@ "node": ">=0.10" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -25991,6 +26341,11 @@ "node": ">=8" } }, + "node_modules/triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, "node_modules/ts-command-line-args": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.0.tgz", @@ -27577,7 +27932,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, "engines": { "node": ">=4" } @@ -27889,7 +28243,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -27947,8 +28300,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utils-merge": { "version": "1.0.1", @@ -29474,6 +29826,38 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "node_modules/winston": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", + "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", + "dependencies": { + "@dabh/diagnostics": "^2.0.2", + "async": "^3.1.0", + "is-stream": "^2.0.0", + "logform": "^2.2.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + }, + "engines": { + "node": ">= 6.4.0" + } + }, + "node_modules/winston-transport": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", + "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -30096,8 +30480,11 @@ "license": "ISC", "dependencies": { "@axelar-network/axelar-local-dev": "2.1.1", + "@confio/relayer": "^0.10.0", "@cosmjs/cosmwasm-stargate": "^0.31.1", - "@cosmjs/stargate": "^0.31.1" + "@cosmjs/stargate": "^0.31.1", + "@types/sinon": "^10.0.20", + "sinon": "^17.0.0" }, "devDependencies": { "@types/node-fetch": "^2.6.5", diff --git a/packages/axelar-local-dev-cosmos/docker/axelar/bin/init_axelar.sh b/packages/axelar-local-dev-cosmos/docker/axelar/bin/init_axelar.sh index ede70b6d..fe04656c 100755 --- a/packages/axelar-local-dev-cosmos/docker/axelar/bin/init_axelar.sh +++ b/packages/axelar-local-dev-cosmos/docker/axelar/bin/init_axelar.sh @@ -33,8 +33,8 @@ mnemonic=$(axelard keys add owner --keyring-backend test --home ${HOME} 2>&1 | t echo ${mnemonic} | tr -d "\n" > ${HOME}/mnemonic.txt echo "Added new key 'owner'" -# Adding a new genesis account named 'owner' with an initial balance of 100000000stake in the blockchain -axelard add-genesis-account owner 100000000${DENOM} \ +# Adding a new genesis account named 'owner' with an initial balance of 100000000000000000000 in the blockchain +axelard add-genesis-account owner 100000000000000000000${DENOM} \ --home ${HOME} \ --keyring-backend test > /dev/null 2>&1 && echo "Added 'owner' to genesis account" diff --git a/packages/axelar-local-dev-cosmos/docker/ibcrelayer/docker-compose.yaml b/packages/axelar-local-dev-cosmos/docker/ibcrelayer/docker-compose.yaml new file mode 100644 index 00000000..6ba6dfa8 --- /dev/null +++ b/packages/axelar-local-dev-cosmos/docker/ibcrelayer/docker-compose.yaml @@ -0,0 +1,19 @@ +version: "3.8" +services: + ibc-relayer: + container_name: ibc-relayer + image: node:18-alpine + working_dir: /app + volumes: + - ./ibc-setup:/app/.ibc-setup + # command: + # - npm i -g @confio/relayer@0.10.0 + entrypoint: + - sh + - -c + - | + npm i -g @confio/relayer@0.10.0 && + ibc-setup init && + ibc-setup ics20 -v && + /bin/sh + # depends_on: [axelar, wasm] diff --git a/packages/axelar-local-dev-cosmos/docker/ibcrelayer/ibc-setup/registry.yaml b/packages/axelar-local-dev-cosmos/docker/ibcrelayer/ibc-setup/registry.yaml new file mode 100644 index 00000000..54ef0362 --- /dev/null +++ b/packages/axelar-local-dev-cosmos/docker/ibcrelayer/ibc-setup/registry.yaml @@ -0,0 +1,21 @@ +version: 1 + +chains: + wasm: + chain_id: wasm + prefix: wasm + gas_price: 0.025uwasm + hd_path: m/44'/1234'/0'/2' + estimated_block_time: 400 + estimated_indexer_time: 60 + rpc: + - http://localhost/wasm-rpc + axelar: + chain_id: axelar + prefix: axelar + gas_price: 0.025uaxl + hd_path: m/44'/1234'/0'/2' + estimated_block_time: 400 + estimated_indexer_time: 60 + rpc: + - http://localhost/axelar-rpc diff --git a/packages/axelar-local-dev-cosmos/docker/wasm/bin/init_and_add_keys.sh b/packages/axelar-local-dev-cosmos/docker/wasm/bin/init_wasm.sh similarity index 92% rename from packages/axelar-local-dev-cosmos/docker/wasm/bin/init_and_add_keys.sh rename to packages/axelar-local-dev-cosmos/docker/wasm/bin/init_wasm.sh index 3f886b39..ffdce9c9 100755 --- a/packages/axelar-local-dev-cosmos/docker/wasm/bin/init_and_add_keys.sh +++ b/packages/axelar-local-dev-cosmos/docker/wasm/bin/init_wasm.sh @@ -28,13 +28,13 @@ mnemonic=$(wasmd keys add owner --keyring-backend test --home ${HOME} 2>&1 | tai echo ${mnemonic} | tr -d "\n" > ${HOME}/mnemonic.txt echo "Added new key 'owner'" -# Adding a new genesis account named 'owner' with an initial balance of 100000000stake in the blockchain -wasmd genesis add-genesis-account owner 100000000${DENOM} \ +# Adding a new genesis account named 'owner' with an initial balance of 100000000000000000000uwasm in the blockchain +wasmd genesis add-genesis-account owner 100000000000000000000${DENOM} \ --home ${HOME} \ --keyring-backend test > /dev/null 2>&1 && echo "Added 'owner' to genesis account" # Generating a new genesis transaction for 'owner' delegating 70000000${DENOM} in the blockchain with the specified chain-id -wasmd genesis gentx owner 70000000${DENOM} \ +wasmd genesis gentx owner 60000000${DENOM} \ --home ${HOME} \ --keyring-backend test \ --moniker ${MONIKER} \ diff --git a/packages/axelar-local-dev-cosmos/docker/wasm/docker-compose.yaml b/packages/axelar-local-dev-cosmos/docker/wasm/docker-compose.yaml index b7009a73..07ce0111 100644 --- a/packages/axelar-local-dev-cosmos/docker/wasm/docker-compose.yaml +++ b/packages/axelar-local-dev-cosmos/docker/wasm/docker-compose.yaml @@ -1,10 +1,10 @@ version: "3.8" services: wasm: - image: cosmwasm/wasmd + image: cosmwasm/wasmd:v0.42.0 container_name: wasm env_file: ".env" - command: "/root/private/bin/init_and_add_keys.sh" + command: "/root/private/bin/init_wasm.sh" volumes: - "./bin:/root/private/bin" - "./.wasm:/root/private/.wasm" diff --git a/packages/axelar-local-dev-cosmos/jest/jest.global-setup.ts b/packages/axelar-local-dev-cosmos/jest/jest.global-setup.ts index 86572c32..5c60840b 100644 --- a/packages/axelar-local-dev-cosmos/jest/jest.global-setup.ts +++ b/packages/axelar-local-dev-cosmos/jest/jest.global-setup.ts @@ -1,5 +1,13 @@ -import { stopAll, startAll } from "../src/docker"; +import { stopAll, startAll, waitForRpc } from "../src/docker"; export default async () => { - // await startAll(); + try { + await waitForRpc("axelar", 5000); + await waitForRpc("wasm", 5000); + } catch (e) { + console.error( + "\nPlease make sure you have started the docker containers by running `npm start` before running tests" + ); + throw e; + } }; diff --git a/packages/axelar-local-dev-cosmos/package.json b/packages/axelar-local-dev-cosmos/package.json index 9d12266c..ce96d9b2 100644 --- a/packages/axelar-local-dev-cosmos/package.json +++ b/packages/axelar-local-dev-cosmos/package.json @@ -8,7 +8,8 @@ "!dist/artifacts" ], "scripts": { - "test": "jest", + "test": "jest --testMatch='**/*.spec.ts' --runInBand", + "test:e2e": "jest --testMatch='**/*.e2e.ts' --runInBand", "clean": "rm -rf src/types dist artifacts", "prettier": "prettier --write 'src/**/*.ts'", "build": "npm run clean && npm run build-ts", @@ -18,8 +19,11 @@ }, "dependencies": { "@axelar-network/axelar-local-dev": "2.1.1", + "@confio/relayer": "^0.10.0", "@cosmjs/cosmwasm-stargate": "^0.31.1", - "@cosmjs/stargate": "^0.31.1" + "@cosmjs/stargate": "^0.31.1", + "@types/sinon": "^10.0.20", + "sinon": "^17.0.0" }, "author": "euro@axelar.network", "license": "ISC", diff --git a/packages/axelar-local-dev-cosmos/src/__tests__/CosmosClient.spec.ts b/packages/axelar-local-dev-cosmos/src/__tests__/CosmosClient.spec.ts deleted file mode 100644 index bc62962e..00000000 --- a/packages/axelar-local-dev-cosmos/src/__tests__/CosmosClient.spec.ts +++ /dev/null @@ -1,75 +0,0 @@ -import path from "path"; -import { CosmosClient } from "../"; - -describe("CosmosClient", () => { - let cosmosClient: CosmosClient; - - beforeAll(async () => { - cosmosClient = await CosmosClient.create(); - }); - - it("should query the balance", async () => { - const owner = await cosmosClient.getOwnerAccount(); - const balance = await cosmosClient.getBalance(owner); - expect(parseInt(balance || "0")).toBeGreaterThan(0); - }); - - it("should be able to upload wasm contract", async () => { - const _path = path.resolve(__dirname, "../..", "wasm/multi_send.wasm"); - const response = await cosmosClient.uploadWasm(_path); - - expect(response).toBeDefined(); - }); - - it("should be able to send tokens to given address", async () => { - const recipient = "wasm1kmfc98hsz9cxq9lyezlpr8d0sh5ct244krg6u5"; - const amount = "1000000"; - const initialBalance = await cosmosClient.getBalance(recipient); - await cosmosClient.fundWallet(recipient, amount); - const balance = await cosmosClient.getBalance(recipient); - expect(parseInt(balance)).toBe(parseInt(initialBalance) + parseInt(amount)); - }); - - it.skip("should be able to execute the wasm contract", async () => { - const _path = path.resolve(__dirname, "../..", "wasm/multi_send.wasm"); - const response = await cosmosClient.uploadWasm(_path); - - const { client } = cosmosClient; - const ownerAddress = await cosmosClient.getOwnerAccount(); - - const { contractAddress } = await client.instantiate( - ownerAddress, - response.codeId, - { - channel: "channel-0", - }, - "amazing random contract", - "auto" - ); - - const denom = cosmosClient.chainInfo.denom; - - console.log( - "Current Balance:", - await cosmosClient.getBalance(ownerAddress), - denom - ); - - const response2 = await client.execute( - ownerAddress, - contractAddress, - { - multi_send_to_evm: { - destination_chain: "ethereum", - destination_address: "0x49324C7f83568861AB1b66E547BB1B66431f1070", - recipients: ["0x49324C7f83568861AB1b66E547BB1B66431f1070"], - }, - }, - "auto", - "test", - [{ amount: "1000000", denom }] - ); - - console.log("Response", response2); - }); -}); diff --git a/packages/axelar-local-dev-cosmos/src/__tests__/cosmos-client.spec.ts b/packages/axelar-local-dev-cosmos/src/__tests__/cosmos-client.spec.ts new file mode 100644 index 00000000..48e7d86d --- /dev/null +++ b/packages/axelar-local-dev-cosmos/src/__tests__/cosmos-client.spec.ts @@ -0,0 +1,36 @@ +import path from "path"; +import { CosmosClient } from ".."; + +describe("CosmosClient", () => { + let wasmClient: CosmosClient; + let axelarClient: CosmosClient; + + beforeAll(async () => { + wasmClient = await CosmosClient.create("wasm"); + axelarClient = await CosmosClient.create("axelar"); + }); + + it("should be able to upload wasm contract", async () => { + const _path = path.resolve(__dirname, "../..", "wasm/multi_send.wasm"); + const response = await wasmClient.uploadWasm(_path); + expect(response).toBeDefined(); + }); + + it("should be able to send tokens to given address on wasm", async () => { + const recipient = "wasm1puut77ku823785u3c7aalwqdrawe3lnjgwt89v"; + const amount = "1000000"; + const initialBalance = await wasmClient.getBalance(recipient); + await wasmClient.fundWallet(recipient, amount); + const balance = await wasmClient.getBalance(recipient); + expect(parseInt(balance)).toBe(parseInt(initialBalance) + parseInt(amount)); + }); + + it("should be able to send tokens to given address on axelar", async () => { + const recipient = "axelar1puut77ku823785u3c7aalwqdrawe3lnjxuv68x"; + const amount = "1000000"; + const initialBalance = await axelarClient.getBalance(recipient); + await axelarClient.fundWallet(recipient, amount); + const balance = await axelarClient.getBalance(recipient); + expect(parseInt(balance)).toBe(parseInt(initialBalance) + parseInt(amount)); + }); +}); diff --git a/packages/axelar-local-dev-cosmos/src/__tests__/ibc-relayer-client.spec.ts b/packages/axelar-local-dev-cosmos/src/__tests__/ibc-relayer-client.spec.ts new file mode 100644 index 00000000..5de64167 --- /dev/null +++ b/packages/axelar-local-dev-cosmos/src/__tests__/ibc-relayer-client.spec.ts @@ -0,0 +1,18 @@ +import { IBCRelayerClient } from "../clients/IBCRelayerClient"; + +describe("IBCRelayerClient", () => { + it.skip("should be able to create a connection and channel", async () => { + const relayerClient = await IBCRelayerClient.create(); + + const response = await relayerClient.initConnection(); + + expect(response.axelar).toBeDefined(); + expect(response.wasm).toBeDefined(); + + const response2 = await relayerClient.createChannel("B"); + + expect(response2).toBeDefined(); + expect(response2!.src).toBeDefined(); + expect(response2!.dest).toBeDefined(); + }); +}); diff --git a/packages/axelar-local-dev-cosmos/src/__tests__/ibc.e2e.ts b/packages/axelar-local-dev-cosmos/src/__tests__/ibc.e2e.ts new file mode 100644 index 00000000..ab26b587 --- /dev/null +++ b/packages/axelar-local-dev-cosmos/src/__tests__/ibc.e2e.ts @@ -0,0 +1,88 @@ +import path from "path"; +import { CosmosClient, IBCRelayerClient } from ".."; +import { ChannelInfo } from "@confio/relayer/build/lib/ibcclient"; + +describe("E2E - IBC", () => { + let wasmClient: CosmosClient; + let axelarClient: CosmosClient; + let relayerClient: IBCRelayerClient; + let srcChannelId: string; + let destChannelId: string; + + beforeAll(async () => { + wasmClient = await CosmosClient.create("wasm"); + axelarClient = await CosmosClient.create("axelar"); + + // Initialize the connection and channel + relayerClient = await IBCRelayerClient.create(); + await relayerClient.initConnection(); + const { dest, src } = await relayerClient.createChannel("B"); + srcChannelId = src.channelId; + destChannelId = dest.channelId; + console.log("Created IBC Channel:", src, dest); + }); + + it("ibc transfer", async () => { + const ownerAddress = await wasmClient.getOwnerAccount(); + const recipient = "axelar1puut77ku823785u3c7aalwqdrawe3lnjxuv68x"; + + // Send tokens to the recipient + await wasmClient.ibcTransfer( + ownerAddress, + recipient, + srcChannelId, + "10000" + ); + + // Get the ibc denom + const ibcDenom = axelarClient.getIBCDenom(destChannelId, "uwasm"); + + // Relay the packet + await relayerClient.relayPackets(); + + // Check the balance on axelar chain + const ibcAmount = await axelarClient.getBalance(recipient, ibcDenom); + expect(parseInt(ibcAmount)).toBeGreaterThan(0); + }); + + // Usually takes 2-3 minutes to run + it("should be able to execute the wasm contract from wasm to axelar chain", async () => { + // Upload the wasm contract + const _path = path.resolve(__dirname, "../..", "wasm/multi_send.wasm"); + const response = await wasmClient.uploadWasm(_path); + + // Instantiate the contract + const { client } = wasmClient; + const ownerAddress = await wasmClient.getOwnerAccount(); + const { contractAddress } = await client.instantiate( + ownerAddress, + response.codeId, + { + channel: srcChannelId, + }, + "amazing random contract", + "auto" + ); + + const denom = wasmClient.chainInfo.denom; + + const execution = await client.execute( + ownerAddress, + contractAddress, + { + multi_send_to_evm: { + destination_chain: "ethereum", + destination_address: "0x49324C7f83568861AB1b66E547BB1B66431f1070", + recipients: ["0x49324C7f83568861AB1b66E547BB1B66431f1070"], + }, + }, + "auto", + "test", + [{ amount: "1000000", denom }] + ); + + await relayerClient.relayPackets(); + + expect(execution).toBeDefined(); + }); +}); diff --git a/packages/axelar-local-dev-cosmos/src/clients/CosmosClient.ts b/packages/axelar-local-dev-cosmos/src/clients/CosmosClient.ts index 06eb9bdc..6e309178 100644 --- a/packages/axelar-local-dev-cosmos/src/clients/CosmosClient.ts +++ b/packages/axelar-local-dev-cosmos/src/clients/CosmosClient.ts @@ -1,37 +1,47 @@ import fs from "fs"; import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; -import { GasPrice } from "@cosmjs/stargate"; +import { GasPrice, StargateClient } from "@cosmjs/stargate"; import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate"; -import { CosmosChainInfo } from "../types"; +import { sha256 } from "@cosmjs/crypto"; +import crypto from "crypto"; +import { CosmosChain, CosmosChainInfo } from "../types"; import { getOwnerAccount } from "../docker"; +import Long from "long"; export class CosmosClient { - chainInfo: Required; - owner: DirectSecp256k1HdWallet; + public chainInfo: Required; + public owner: DirectSecp256k1HdWallet; public client: SigningCosmWasmClient; - gasPrice: GasPrice; + stargateClient: StargateClient; + public gasPrice: GasPrice; private constructor( chainInfo: Required, owner: DirectSecp256k1HdWallet, client: SigningCosmWasmClient, - gasPrice: GasPrice + gasPrice: GasPrice, + starGateClient: StargateClient ) { this.chainInfo = chainInfo; this.owner = owner; this.client = client; this.gasPrice = gasPrice; + this.stargateClient = starGateClient; } - static async create(config: Omit = {}) { + static async create( + chain: CosmosChain = "wasm", + config: Omit = { prefix: chain } + ) { + const defaultDenom = chain === "wasm" ? "uwasm" : "uaxl"; const chainInfo = { - denom: config.denom || "uwasm", - lcdUrl: config.lcdUrl || "http://localhost/wasm-lcd", - rpcUrl: config.rpcUrl || "http://localhost/wasm-rpc", + denom: config.denom || defaultDenom, + lcdUrl: config.lcdUrl || `http://localhost/${chain}-lcd`, + rpcUrl: config.rpcUrl || `http://localhost/${chain}-rpc`, }; const walletOptions = { - prefix: "wasm", + prefix: chain, }; const gasPrice = GasPrice.fromString(`1${chainInfo.denom}`); @@ -39,7 +49,7 @@ export class CosmosClient { gasPrice, }; - const { address, mnemonic } = await getOwnerAccount("wasm"); + const { address, mnemonic } = await getOwnerAccount(chain); const owner = await DirectSecp256k1HdWallet.fromMnemonic( mnemonic, @@ -52,6 +62,8 @@ export class CosmosClient { clientOptions ); + const stargateClient = await StargateClient.connect(chainInfo.rpcUrl); + return new CosmosClient( { ...chainInfo, @@ -59,51 +71,108 @@ export class CosmosClient { mnemonic, address, }, + prefix: chain, }, owner, client, - gasPrice + gasPrice, + stargateClient ); } - getBalance(address: string) { + getBalance(address: string, denom?: string) { return this.client - .getBalance(address, this.chainInfo.denom) + .getBalance(address, denom || this.chainInfo.denom) .then((res) => res.amount); } + async getBalances(address: string) { + return this.stargateClient.getAllBalances(address); + } + getChainInfo(): Omit { return { + prefix: this.chainInfo.prefix, denom: this.chainInfo.denom, lcdUrl: this.chainInfo.lcdUrl, rpcUrl: this.chainInfo.rpcUrl, }; } + async ibcTransfer( + sender: string, + receiver: string, + sourceChannel: string, + amount: string + ) { + const msgIBCTransfer = { + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: { + sourcePort: "transfer", + sourceChannel, + token: { + denom: this.chainInfo.denom, + amount: amount, + }, + sender: sender, + receiver: receiver, + timeoutTimestamp: Long.fromNumber(Date.now() + 600_000).multiply( + 1_000_000 + ), + }, + }; + + return this.client.signAndBroadcast( + sender, + [msgIBCTransfer], + "auto", + "IBC Transfer" + ); + } + + getIBCDenom(channel: string, denom: string, port = "transfer") { + const path = `${port}/${channel}/${denom}`; + // Compute the SHA-256 hash of the path + const hash = crypto.createHash("sha256").update(path).digest(); + + // Convert the hash to a hexadecimal representation + const hexHash = hash.toString("hex").toUpperCase(); + + // Construct the denom by prefixing the hex hash with 'ibc/' + return `ibc/${hexHash}`; + } + async fundWallet(address: string, amount: string) { const ownerAddress = await this.getOwnerAccount(); const gasPrice = GasPrice.fromString(`1${this.chainInfo.denom}`); - return this.client.sendTokens( - ownerAddress, - address, - [ - { - amount, - denom: this.chainInfo.denom, - }, - ], - { - amount: [ + return this.client + .sendTokens( + ownerAddress, + address, + [ { - amount: gasPrice.amount.toString(), - denom: gasPrice.denom, + amount, + denom: this.chainInfo.denom, }, ], - gas: "100000", - } - ); + { + amount: [ + { + amount: gasPrice.amount.toString(), + denom: gasPrice.denom, + }, + ], + gas: "100000", + } + ) + .then((res) => { + if (res.code !== 0) { + throw new Error(res.rawLog); + } + return res; + }); } async uploadWasm(path: string) { diff --git a/packages/axelar-local-dev-cosmos/src/clients/IBCRelayerClient.ts b/packages/axelar-local-dev-cosmos/src/clients/IBCRelayerClient.ts new file mode 100644 index 00000000..21717503 --- /dev/null +++ b/packages/axelar-local-dev-cosmos/src/clients/IBCRelayerClient.ts @@ -0,0 +1,142 @@ +import { Order } from "cosmjs-types/ibc/core/channel/v1/channel"; +import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; +import { IbcClient, Link, RelayedHeights } from "@confio/relayer"; +import { ChannelPair } from "@confio/relayer/build/lib/link"; +import { CosmosClient } from "../clients/CosmosClient"; +import { relay } from "@axelar-network/axelar-local-dev"; +import { convertCosmosAddress } from "../docker"; + +export class IBCRelayerClient { + axelarClient: CosmosClient; + wasmClient: CosmosClient; + link?: Link; + public channel?: ChannelPair; + public lastRelayedHeight: RelayedHeights = {}; + public relayerAccount: DirectSecp256k1HdWallet; + + private constructor( + axelarClient: CosmosClient, + wasmClient: CosmosClient, + relayer: DirectSecp256k1HdWallet + ) { + this.axelarClient = axelarClient; + this.wasmClient = wasmClient; + this.relayerAccount = relayer; + } + + static async create() { + const axelarClient = await CosmosClient.create("axelar"); + const wasmClient = await CosmosClient.create("wasm"); + const relayer = await DirectSecp256k1HdWallet.generate(12, { + prefix: "wasm", + }); + + // Fund the relayer address + const relayerAddress = await relayer + .getAccounts() + .then((accounts) => accounts[0].address); + const relayerAxelarAddress = convertCosmosAddress(relayerAddress, "axelar"); + + await wasmClient.fundWallet(relayerAddress, "100000000"); + console.log("Funded relayer address on wasm:", relayerAddress); + await axelarClient.fundWallet(relayerAxelarAddress, "100000000"); + console.log("Funded relayer address on axelar:", relayerAxelarAddress); + + // check the fund + const balance = await wasmClient.getBalance(relayerAddress); + console.log("Relayer wasm balance", balance); + const axelarBalance = await axelarClient.getBalance(relayerAxelarAddress); + console.log("Relayer axelar balance", axelarBalance); + + return new IBCRelayerClient(axelarClient, wasmClient, relayer); + } + + getRelayerAddress() { + return this.relayerAccount + .getAccounts() + .then((accounts) => accounts[0].address); + } + + async getIBCClient(client: CosmosClient) { + const relayerAddress = await this.getRelayerAddress(); + const prefix = client.getChainInfo().prefix; + const relayer = await DirectSecp256k1HdWallet.fromMnemonic( + this.relayerAccount.mnemonic, + { + prefix, + } + ); + + return IbcClient.connectWithSigner( + client.chainInfo.rpcUrl, + relayer, + convertCosmosAddress(relayerAddress, prefix), + { + gasPrice: client.gasPrice, + estimatedBlockTime: 400, + estimatedIndexerTime: 60, + } + ); + } + + async initConnection() { + const axelarIBCClient = await this.getIBCClient(this.axelarClient); + const wasmIBCClient = await this.getIBCClient(this.wasmClient); + + if (this.link) + return { + axelar: { + connectionId: this.link.endA.connectionID, + }, + wasm: { + connectionId: this.link.endB.connectionID, + }, + }; + + this.link = await Link.createWithNewConnections( + axelarIBCClient, + wasmIBCClient + ); + + return { + axelar: { + connectionId: this.link.endA.connectionID, + }, + wasm: { + connectionId: this.link.endB.connectionID, + }, + }; + } + + async createChannel(sender: "A" | "B") { + if (!this.link) { + throw new Error("Link not initialized"); + } + + if (this.channel) return this.channel; + + this.channel = await this.link?.createChannel( + sender, + "transfer", + "transfer", + Order.ORDER_UNORDERED, + "ics20-1" + ); + + return this.channel; + } + + async relayPackets() { + if (!this.link) { + throw new Error("Link not initialized"); + } + + this.lastRelayedHeight = await this.link!.checkAndRelayPacketsAndAcks( + this.lastRelayedHeight, + 2, + 6 + ); + + return this.lastRelayedHeight; + } +} diff --git a/packages/axelar-local-dev-cosmos/src/clients/index.ts b/packages/axelar-local-dev-cosmos/src/clients/index.ts index cb892f77..ea285208 100644 --- a/packages/axelar-local-dev-cosmos/src/clients/index.ts +++ b/packages/axelar-local-dev-cosmos/src/clients/index.ts @@ -1 +1,2 @@ export * from "./CosmosClient"; +export * from "./IBCRelayerClient"; diff --git a/packages/axelar-local-dev-cosmos/src/docker/start.ts b/packages/axelar-local-dev-cosmos/src/docker/start.ts index c540ee9e..10a73b67 100644 --- a/packages/axelar-local-dev-cosmos/src/docker/start.ts +++ b/packages/axelar-local-dev-cosmos/src/docker/start.ts @@ -63,7 +63,7 @@ export async function start( await compose.upOne(chain, config); // Wait for API servers to start - await waitForRpc(chain, options); + await waitForRpc(chain); await waitForLcd(chain); const rpcUrl = `http://localhost/${chain}-rpc`; @@ -73,6 +73,7 @@ export async function start( console.log(`LCD server for ${chain} is started at ${lcdUrl}`); return { + prefix: chain, owner: await getOwnerAccount(chain), denom: getChainDenom(chain), lcdUrl, diff --git a/packages/axelar-local-dev-cosmos/src/docker/utils.ts b/packages/axelar-local-dev-cosmos/src/docker/utils.ts index 6ad9b5d1..97ada863 100644 --- a/packages/axelar-local-dev-cosmos/src/docker/utils.ts +++ b/packages/axelar-local-dev-cosmos/src/docker/utils.ts @@ -7,6 +7,7 @@ import { defaultConfig as wasmConfig } from "../wasm"; import { ChainConfig, CosmosChain } from "../types"; import { logger } from "@axelar-network/axelar-local-dev"; import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; +import bech32 from "bech32"; export function getChainDenom(chain: CosmosChain) { return chain === "axelar" ? "uaxl" : "uwasm"; @@ -20,6 +21,11 @@ export function getChainConfig(chain: CosmosChain) { return chain === "axelar" ? axelarConfig : wasmConfig; } +export function convertCosmosAddress(address: string, prefix: string) { + const decoded = bech32.decode(address); + return bech32.encode(prefix, decoded.words); +} + export function createContainerEnv(chain: CosmosChain, options: ChainConfig) { const { dockerPath } = options; const envPath = path.join(dockerPath, ".env"); @@ -49,9 +55,8 @@ export async function getOwnerAccount(chain: CosmosChain) { * Periodically fetching the healthcheck url until the response code is 200. * If response isn't 200 within {timeout}, throws an error. */ -export async function waitForRpc(chain: CosmosChain, config: ChainConfig) { +export async function waitForRpc(chain: CosmosChain, timeout = 120000) { const start = Date.now(); - const timeout = 60000; const interval = 3000; const url = `http://localhost/${chain}-rpc/health`; let status = 0; @@ -61,7 +66,6 @@ export async function waitForRpc(chain: CosmosChain, config: ChainConfig) { if (status === 200) { break; } - console.log("status", status); } catch (e) { // do nothing } @@ -72,10 +76,9 @@ export async function waitForRpc(chain: CosmosChain, config: ChainConfig) { } } -export async function waitForLcd(chain: CosmosChain) { +export async function waitForLcd(chain: CosmosChain, timeout = 60000) { const testUrl = "cosmos/base/tendermint/v1beta1/node_info"; const start = Date.now(); - const timeout = 60000; const interval = 3000; const url = `http://localhost/${chain}-lcd/${testUrl}`; let result, network; diff --git a/packages/axelar-local-dev-cosmos/src/types.ts b/packages/axelar-local-dev-cosmos/src/types.ts index 325e722b..e0a63bea 100644 --- a/packages/axelar-local-dev-cosmos/src/types.ts +++ b/packages/axelar-local-dev-cosmos/src/types.ts @@ -3,6 +3,7 @@ export interface CosmosChainInfo { mnemonic: string; address: string; }; + prefix: string; denom?: string; rpcUrl?: string; lcdUrl?: string;