Feature/validator client upgrade (#675)

* Upgrading cosmos client to v0.25.5

* Formatting

* Renamed stakeDenom to prefix

* Added a denom field to the client

* New version needs a denom in the static methods

* ibid

* Formatting

* Renaming bech32prefix to prefix

* Adding a weird 'u' in the nymGasPrice

* Changing to use denom instead of prefix in nymGasPrice

* Alphabetizing fields

* Renaming method to something a bit more sane

* Using prefix, not denom, to build gas price

* Hardcoding an unavoidable and ugly manual conversion into the stargate helper

* denom is correct, for use in getBalance
This commit is contained in:
Dave Hrycyszyn
2021-07-06 12:50:26 +01:00
committed by GitHub
parent cb33871934
commit 427893efef
5 changed files with 157 additions and 156 deletions
+99 -102
View File
@@ -1,6 +1,6 @@
{
"name": "@nymproject/nym-validator-client",
"version": "0.11.1",
"version": "0.14.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -357,69 +357,78 @@
"sha.js": "^2.4.11"
}
},
"@cosmjs/cosmwasm": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm/-/cosmwasm-0.24.1.tgz",
"integrity": "sha512-2NQznO9AaZVJIDbc01KlDkZ4KKdnuJt680DXQDsPmhvz4ZA6weUyyuauxHZTQX8RHCaWGWyGxXDWdsWe70xyIg==",
"@cosmjs/amino": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.25.5.tgz",
"integrity": "sha512-q9tU2b9hJ3S/KxYCLSyiZCfkaidbSPBr2sJ5HPLxz48y5O4k9sYM7bPa0zioeePaIBnby3AOgyjucVxlbzUlYg==",
"requires": {
"@cosmjs/cosmwasm-launchpad": "^0.24.1"
"@cosmjs/crypto": "^0.25.5",
"@cosmjs/encoding": "^0.25.5",
"@cosmjs/math": "^0.25.5",
"@cosmjs/utils": "^0.25.5"
}
},
"@cosmjs/cosmwasm": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm/-/cosmwasm-0.25.5.tgz",
"integrity": "sha512-PsK28ARcow5hEd+hKAdGsjtjz/g5UMtPpSWD7l1WxWhuASLmJVXFebBUPJAu3CDeFG3FrlCRP5J8tLvJOisuJQ==",
"requires": {
"@cosmjs/cosmwasm-launchpad": "^0.25.5"
}
},
"@cosmjs/cosmwasm-launchpad": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-launchpad/-/cosmwasm-launchpad-0.24.1.tgz",
"integrity": "sha512-B4rNOlH88x0vRlGyg8FbXpXcGS+ODM1i1XEM3q/XNu/rxbbzGw3wOrO3nj/GRZT1+8nej1R9qSxIrsJcZ6bXNA==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-launchpad/-/cosmwasm-launchpad-0.25.5.tgz",
"integrity": "sha512-9/Z8m9rfovtgchN1thcdVBEBXCrh5clVNgpVp1rpbkUSSGA7T5tCR8H1qX0+Yd3HLRh212O5EnCfzzXjNxR21A==",
"requires": {
"@cosmjs/crypto": "^0.24.1",
"@cosmjs/encoding": "^0.24.1",
"@cosmjs/launchpad": "^0.24.1",
"@cosmjs/math": "^0.24.1",
"@cosmjs/utils": "^0.24.1",
"@cosmjs/crypto": "^0.25.5",
"@cosmjs/encoding": "^0.25.5",
"@cosmjs/launchpad": "^0.25.5",
"@cosmjs/math": "^0.25.5",
"@cosmjs/utils": "^0.25.5",
"pako": "^2.0.2"
}
},
"@cosmjs/cosmwasm-stargate": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.24.1.tgz",
"integrity": "sha512-ij4aZ4igIa/OYl72LqFdnRe9FReaA7MyBY6txyi8N+mVnF+DSY+0J8S5IIkv8654JAo7sc03YqxTtc3uY/hwTA==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.25.5.tgz",
"integrity": "sha512-lUwjXMnVO+8iZtqwKr4hEBgA9q03AqAhUBNNyyG8oeTpgASrQ1ZlLjjmBWgvEpw4JokRduDf7il+NNENjaeAhQ==",
"requires": {
"@cosmjs/cosmwasm-launchpad": "^0.24.1",
"@cosmjs/crypto": "^0.24.1",
"@cosmjs/encoding": "^0.24.1",
"@cosmjs/launchpad": "^0.24.1",
"@cosmjs/math": "^0.24.1",
"@cosmjs/proto-signing": "^0.24.1",
"@cosmjs/stargate": "^0.24.1",
"@cosmjs/tendermint-rpc": "^0.24.1",
"@cosmjs/utils": "^0.24.1",
"@cosmjs/amino": "^0.25.5",
"@cosmjs/cosmwasm-launchpad": "^0.25.5",
"@cosmjs/crypto": "^0.25.5",
"@cosmjs/encoding": "^0.25.5",
"@cosmjs/math": "^0.25.5",
"@cosmjs/proto-signing": "^0.25.5",
"@cosmjs/stargate": "^0.25.5",
"@cosmjs/tendermint-rpc": "^0.25.5",
"@cosmjs/utils": "^0.25.5",
"long": "^4.0.0",
"pako": "^2.0.2",
"protobufjs": "~6.10.2"
}
},
"@cosmjs/crypto": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.24.1.tgz",
"integrity": "sha512-GPhaWmQO06mXldKj/b+oKF5o3jMNfRKpAw+Q8XQhrD7ItinVPDMu8Xgl6frUXWTUdgpYwqpvqOcpm85QUsYV0Q==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.25.5.tgz",
"integrity": "sha512-i0Nfbk4JXAwyKNGPFu0o1xV6IJUbYmmveySytbU/yweybcZppxoczjSQ1sGrUaLVLvgfcpfwZte3jKqDR67+dg==",
"requires": {
"@cosmjs/encoding": "^0.24.1",
"@cosmjs/math": "^0.24.1",
"@cosmjs/utils": "^0.24.1",
"@cosmjs/encoding": "^0.25.5",
"@cosmjs/math": "^0.25.5",
"@cosmjs/utils": "^0.25.5",
"bip39": "^3.0.2",
"bn.js": "^4.11.8",
"elliptic": "^6.5.3",
"js-sha3": "^0.8.0",
"libsodium-wrappers": "^0.7.6",
"pbkdf2": "^3.1.1",
"ripemd160": "^2.0.2",
"sha.js": "^2.4.11",
"unorm": "^1.5.0"
"sha.js": "^2.4.11"
}
},
"@cosmjs/encoding": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.24.1.tgz",
"integrity": "sha512-PMr+gaXAuM0XgjeXwB1zdX1QI0t+PgVhbmjgI/RSgswDzdExNH97qUopecL0/HG3p64vhIT/6ZjXYYTljZL7WA==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.25.5.tgz",
"integrity": "sha512-QT7MaPBiMeCaMJ6VZZKeOqDQlAxMEzTFjBFhbkdyx5DVRc4dPOVO4HbTggmIN5/eizIv4/CNJSVTR//tO53J0A==",
"requires": {
"base64-js": "^1.3.0",
"bech32": "^1.1.4",
@@ -427,101 +436,102 @@
}
},
"@cosmjs/json-rpc": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.24.1.tgz",
"integrity": "sha512-kZ6473O81TRMyP1XomnvgIny3nBY//JngnpGJSDZyYjlIm6t5BhLqCuZJiuMOc937RyHKmqUQaOUtDA7X0TKYg==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.25.5.tgz",
"integrity": "sha512-WFDallAolxBqB8V/mYxU0riF/OBoc6Fc2DDsZhds5xOZxeN9sTX0qWhu1UiFyURw4Z9D+SjB9QngqSDBTMTdjw==",
"requires": {
"@cosmjs/stream": "^0.24.1",
"@cosmjs/stream": "^0.25.5",
"xstream": "^11.14.0"
}
},
"@cosmjs/launchpad": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/launchpad/-/launchpad-0.24.1.tgz",
"integrity": "sha512-syqVGKRH6z1vw4DdAJOSu4OgUXJdkXQozqvDde0cXYwnvhb7EXGSg5CTtp+2GqTBJuNVfMZ2DSvrC2Ig8cWBQQ==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/launchpad/-/launchpad-0.25.5.tgz",
"integrity": "sha512-7zsFWQHLAiOUBXV/QWvffI/5Ssma67lEO3V01DZ8CtfnWiO4bCSbnU2sslSAH11RkrPdNfRBM7WOBczMMigIzw==",
"requires": {
"@cosmjs/crypto": "^0.24.1",
"@cosmjs/encoding": "^0.24.1",
"@cosmjs/math": "^0.24.1",
"@cosmjs/utils": "^0.24.1",
"@cosmjs/amino": "^0.25.5",
"@cosmjs/crypto": "^0.25.5",
"@cosmjs/encoding": "^0.25.5",
"@cosmjs/math": "^0.25.5",
"@cosmjs/utils": "^0.25.5",
"axios": "^0.21.1",
"fast-deep-equal": "^3.1.3"
}
},
"@cosmjs/math": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.24.1.tgz",
"integrity": "sha512-eBQk8twgzmpHFCVkoNjTZhsZwWRbR+JXt0FhjXJoD85SBm4K8b2OnOyTg68uPHVKOJjLRwzyRVYgMrg5TBVgwQ==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.25.5.tgz",
"integrity": "sha512-LWovT1uTHlr+VEce27/14Wrgc4INJYOYk1+ncyvbZertixNFH6OMnc9Xkk0DIV4RYmW+/fvB9kCXVnNtQGSuHg==",
"requires": {
"bn.js": "^4.11.8"
}
},
"@cosmjs/proto-signing": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.24.1.tgz",
"integrity": "sha512-/rnyNx+FlG6b6O+igsb42eMN1/RXY+pTrNnAE8/YZaRloP9A6MXiTMO5JdYSTcjaD0mEVhejiy96bcyflKYXBg==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.25.5.tgz",
"integrity": "sha512-YWVp+dGHt7v6ZKjOs8CI9xkpOV49eweHbYMv/vCVYF4cEh0kWwy2WzbWIkUH9zwwUqCxigVOTBYUCfbsjEbfug==",
"requires": {
"@cosmjs/launchpad": "^0.24.1",
"@cosmjs/amino": "^0.25.5",
"long": "^4.0.0",
"protobufjs": "~6.10.2"
}
},
"@cosmjs/socket": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.24.1.tgz",
"integrity": "sha512-L8zxUzn1C01u5iwLY9u+G8z2WEExU5G7XDRaoVvX22oVBy0wUaxBxmIDsmC/usSd2giYGy1/iVCd5132DwnKbw==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.25.5.tgz",
"integrity": "sha512-wcJVbD4xlF4+5hMum4tOmAy5ppX+E9qrB9Pvt3T7BK+6T5uobxiBQCLEiDwHP3n42RBj+xQWJrScPf5IEWmZKg==",
"requires": {
"@cosmjs/stream": "^0.24.1",
"@cosmjs/stream": "^0.25.5",
"isomorphic-ws": "^4.0.1",
"ws": "^6.2.0",
"ws": "^7",
"xstream": "^11.14.0"
}
},
"@cosmjs/stargate": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.24.1.tgz",
"integrity": "sha512-JQnrMML3gHCtP3vtDRz5nzIxZ9UzbFVJzgJSSooHEc3VtOfojxs4XQOeH3w6nrg9jWm6a4VIFWA0lRQQ/9/05g==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.25.5.tgz",
"integrity": "sha512-cOZ+fOC16YT7W2vjBnnk9oJfuIlB02KdK6dn6aigMd4mx+7DS2jvNslpQrfKmtrwB9AVsgc6tklBkYwG5qAuKQ==",
"requires": {
"@confio/ics23": "^0.6.3",
"@cosmjs/encoding": "^0.24.1",
"@cosmjs/launchpad": "^0.24.1",
"@cosmjs/math": "^0.24.1",
"@cosmjs/proto-signing": "^0.24.1",
"@cosmjs/stream": "^0.24.1",
"@cosmjs/tendermint-rpc": "^0.24.1",
"@cosmjs/utils": "^0.24.1",
"@cosmjs/amino": "^0.25.5",
"@cosmjs/encoding": "^0.25.5",
"@cosmjs/math": "^0.25.5",
"@cosmjs/proto-signing": "^0.25.5",
"@cosmjs/stream": "^0.25.5",
"@cosmjs/tendermint-rpc": "^0.25.5",
"@cosmjs/utils": "^0.25.5",
"long": "^4.0.0",
"protobufjs": "~6.10.2"
}
},
"@cosmjs/stream": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.24.1.tgz",
"integrity": "sha512-NFoc7kA90vgYRMXzsDnTTTXsH5kCHIhmhEUoQptx5A7LqTjvJScnP1EU+MoT9231L6HVtx0RDIaUulouFGWkcw==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.25.5.tgz",
"integrity": "sha512-a+0sDNKZTxw9p4j5tl7SI0siMTii7AQot1+5vkH5BkQoAv3C3D8jagPouUz3RUFuh13qftPxPLiHzDFLNSjTnQ==",
"requires": {
"xstream": "^11.14.0"
}
},
"@cosmjs/tendermint-rpc": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.24.1.tgz",
"integrity": "sha512-2s7SmoLjLY9Bq6D4/CkOnwm4WZBSHo6T3oTTKE6NLD+2A8BLcjdDnA49eLe3XzkMtVyfLvfrmoEXkCadfDFPOw==",
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.25.5.tgz",
"integrity": "sha512-WlUCFVdhbwA3IDA1C858S8WOtLseZLXKTdj5fz1sTKSBmtrig4l1ZMKHHlZRprvmjSpkpbjgSQU+RjjvBd75BA==",
"requires": {
"@cosmjs/crypto": "^0.24.1",
"@cosmjs/encoding": "^0.24.1",
"@cosmjs/json-rpc": "^0.24.1",
"@cosmjs/math": "^0.24.1",
"@cosmjs/socket": "^0.24.1",
"@cosmjs/stream": "^0.24.1",
"@cosmjs/crypto": "^0.25.5",
"@cosmjs/encoding": "^0.25.5",
"@cosmjs/json-rpc": "^0.25.5",
"@cosmjs/math": "^0.25.5",
"@cosmjs/socket": "^0.25.5",
"@cosmjs/stream": "^0.25.5",
"axios": "^0.21.1",
"readonly-date": "^1.0.0",
"xstream": "^11.14.0"
}
},
"@cosmjs/utils": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.24.1.tgz",
"integrity": "sha512-VA3WFx1lMFb7esp9BqHWkDgMvHoA3D9w+uDRvWhVRpUpDc7RYHxMbWExASjz+gNblTCg556WJGzF64tXnf9tdQ=="
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.25.5.tgz",
"integrity": "sha512-U4YdgJadFgXWblthgyXqP28Yw5rsw2IX/cOES0pa6fiB81hoYl2LXqXiuKp2yVPoAgk8JpkFh3i5KchcD9muJg=="
},
"@eslint/eslintrc": {
"version": "0.4.1",
@@ -1005,11 +1015,6 @@
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
"dev": true
},
"async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
},
"at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
@@ -3618,11 +3623,6 @@
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
"dev": true
},
"unorm": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -3760,12 +3760,9 @@
}
},
"ws": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
"requires": {
"async-limiter": "~1.0.0"
}
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.2.tgz",
"integrity": "sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ=="
},
"xstream": {
"version": "11.14.0",
+6 -6
View File
@@ -35,11 +35,11 @@
"typescript": "^4.1.3"
},
"dependencies": {
"@cosmjs/cosmwasm": "^0.24.1",
"@cosmjs/cosmwasm-stargate": "^0.24.1",
"@cosmjs/crypto": "^0.24.1",
"@cosmjs/launchpad": "^0.24.1",
"@cosmjs/math": "^0.24.1",
"@cosmjs/proto-signing": "^0.24.1"
"@cosmjs/cosmwasm": "^0.25.5",
"@cosmjs/cosmwasm-stargate": "^0.25.5",
"@cosmjs/crypto": "^0.25.5",
"@cosmjs/launchpad": "^0.25.5",
"@cosmjs/math": "^0.25.5",
"@cosmjs/proto-signing": "^0.25.5"
}
}
+39 -37
View File
@@ -33,52 +33,52 @@ export { displayAmountToNative, nativeCoinToDisplay, printableCoin, printableBal
export { nymGasLimits, nymGasPrice }
export default class ValidatorClient {
private readonly stakeDenom: string;
urls: string[];
private readonly client: INetClient | IQueryClient
private mixNodesCache: MixnodesCache;
private gatewayCache: GatewaysCache
private readonly contractAddress: string;
// for some reason typescript thinks it's better to not be explicit about a trivial type...
// eslint-disable-next-line @typescript-eslint/no-inferrable-types
private readonly denom: string;
private failedRequests: number = 0;
private gatewayCache: GatewaysCache
private mixNodesCache: MixnodesCache;
private readonly prefix: string;
urls: string[];
private constructor(urls: string[], client: INetClient | IQueryClient, contractAddress: string, stakeDenom: string) {
private constructor(urls: string[], client: INetClient | IQueryClient, contractAddress: string, prefix: string) {
this.urls = urls;
this.client = client;
this.mixNodesCache = new MixnodesCache(client, 100);
this.gatewayCache = new GatewaysCache(client, 100);
this.contractAddress = contractAddress;
this.stakeDenom = stakeDenom;
this.prefix = prefix;
this.denom = "u" + prefix;
}
// allows also entering 'string' by itself for backwards compatibility
static async connect(contractAddress: string, mnemonic: string, urls: string | string[], stakeDenom: string): Promise<ValidatorClient> {
const validatorUrls = this.dealWithValidatorUrls(urls)
const wallet = await ValidatorClient.buildWallet(mnemonic);
static async connect(contractAddress: string, mnemonic: string, urls: string | string[], prefix: string): Promise<ValidatorClient> {
const validatorUrls = this.ensureArray(urls)
const wallet = await ValidatorClient.buildWallet(mnemonic, prefix);
// if we have more than a single validator, try to perform initial connection until we succeed or run out of options
if (validatorUrls.length > 1) {
for (let i = 0; i < validatorUrls.length; i++) {
console.log("Attempting initial connection to", validatorUrls[0])
const netClient = await NetClient.connect(wallet, validatorUrls[0], stakeDenom).catch((_) => ValidatorClient.moveArrayHeadToBack(validatorUrls))
const netClient = await NetClient.connect(wallet, validatorUrls[0], prefix).catch((_) => ValidatorClient.moveArrayHeadToBack(validatorUrls))
if (netClient !== undefined) {
return new ValidatorClient(validatorUrls, netClient, contractAddress, stakeDenom);
return new ValidatorClient(validatorUrls, netClient, contractAddress, prefix);
}
console.log("Initial connection to", validatorUrls[0], "failed")
}
} else {
const netClient = await NetClient.connect(wallet, validatorUrls[0], stakeDenom)
return new ValidatorClient(validatorUrls, netClient, contractAddress, stakeDenom);
const netClient = await NetClient.connect(wallet, validatorUrls[0], prefix)
return new ValidatorClient(validatorUrls, netClient, contractAddress, prefix);
}
throw new Error("None of the provided validators seem to be alive")
}
// allows also entering 'string' by itself for backwards compatibility
static async connectForQuery(contractAddress: string, urls: string | string[], stakeDenom: string): Promise<ValidatorClient> {
const validatorUrls = this.dealWithValidatorUrls(urls)
static async connectForQuery(contractAddress: string, urls: string | string[], prefix: string): Promise<ValidatorClient> {
const validatorUrls = this.ensureArray(urls)
// if we have more than a single validator, try to perform initial connection until we succeed or run out of options
if (validatorUrls.length > 1) {
@@ -86,19 +86,19 @@ export default class ValidatorClient {
console.log("Attempting initial connection to", validatorUrls[0])
const queryClient = await QueryClient.connect(validatorUrls[0]).catch((_) => ValidatorClient.moveArrayHeadToBack(validatorUrls))
if (queryClient !== undefined) {
return new ValidatorClient(validatorUrls, queryClient, contractAddress, stakeDenom)
return new ValidatorClient(validatorUrls, queryClient, contractAddress, prefix)
}
console.log("Initial connection to", validatorUrls[0], "failed")
}
} else {
const queryClient = await QueryClient.connect(validatorUrls[0])
return new ValidatorClient(validatorUrls, queryClient, contractAddress, stakeDenom)
return new ValidatorClient(validatorUrls, queryClient, contractAddress, prefix)
}
throw new Error("None of the provided validators seem to be alive")
}
private static dealWithValidatorUrls(urls: string | string[]): string[] {
private static ensureArray(urls: string | string[]): string[] {
let validatorsUrls: string[] = []
if (typeof urls === "string") {
validatorsUrls = [urls]
@@ -134,7 +134,7 @@ export default class ValidatorClient {
ValidatorClient.moveArrayHeadToBack(this.urls)
}
// and change validator to the front one and rethrow the error
return await this.changeValidator(this.urls[0]).then(() => {throw error})
return await this.changeValidator(this.urls[0]).then(() => { throw error })
} else {
// rethrow the error
throw error
@@ -157,7 +157,7 @@ export default class ValidatorClient {
// It is responsibility of the caller to ensure the input array is non-empty
private static moveArrayHeadToBack<T>(arr: T[]) {
const head = <T> arr.shift()
const head = <T>arr.shift()
arr.push(head)
}
@@ -200,18 +200,19 @@ export default class ValidatorClient {
* @param mnemonic A mnemonic from which to generate a public/private keypair.
* @returns the address for this client wallet
*/
static async mnemonicToAddress(mnemonic: string): Promise<string> {
const wallet = await ValidatorClient.buildWallet(mnemonic);
const [{address}] = await wallet.getAccounts()
static async mnemonicToAddress(mnemonic: string, prefix: string): Promise<string> {
const wallet = await ValidatorClient.buildWallet(mnemonic, prefix);
const [{ address }] = await wallet.getAccounts()
return address
}
static async buildWallet(mnemonic: string): Promise<DirectSecp256k1HdWallet> {
return DirectSecp256k1HdWallet.fromMnemonic(mnemonic, undefined, "hal");
static async buildWallet(mnemonic: string, prefix: string): Promise<DirectSecp256k1HdWallet> {
const signerOptions = { prefix: prefix };
return DirectSecp256k1HdWallet.fromMnemonic(mnemonic, signerOptions);
}
getBalance(address: string): Promise<Coin | null> {
return this.client.getBalance(address, this.stakeDenom).catch((err) => this.handleRequestFailure(err));
return this.client.getBalance(address, this.denom).catch((err) => this.handleRequestFailure(err));
}
async getStateParams(): Promise<StateParams> {
@@ -248,7 +249,7 @@ export default class ValidatorClient {
async minimumMixnodeBond(): Promise<Coin> {
const stateParams = await this.getStateParams()
// we trust the contract to return a valid number
return coin(Number(stateParams.minimum_mixnode_bond), this.stakeDenom)
return coin(Number(stateParams.minimum_mixnode_bond), this.prefix)
}
/**
@@ -394,7 +395,7 @@ export default class ValidatorClient {
async minimumGatewayBond(): Promise<Coin> {
const stateParams = await this.getStateParams()
// we trust the contract to return a valid number
return coin(Number(stateParams.minimum_gateway_bond), this.stakeDenom)
return coin(Number(stateParams.minimum_gateway_bond), this.prefix)
}
/**
@@ -402,7 +403,7 @@ export default class ValidatorClient {
*/
async bondGateway(gateway: Gateway, bond: Coin): Promise<ExecuteResult> {
if (this.client instanceof NetClient) {
const result = await this.client.executeContract(this.client.clientAddress, this.contractAddress, {bond_gateway: {gateway: gateway}}, "adding gateway", [bond]).catch((err) => this.handleRequestFailure(err));
const result = await this.client.executeContract(this.client.clientAddress, this.contractAddress, { bond_gateway: { gateway: gateway } }, "adding gateway", [bond]).catch((err) => this.handleRequestFailure(err));
console.log(`account ${this.client.clientAddress} added gateway with ${gateway.host}`);
return result;
} else {
@@ -415,7 +416,7 @@ export default class ValidatorClient {
*/
async unbondGateway(): Promise<ExecuteResult> {
if (this.client instanceof NetClient) {
const result = await this.client.executeContract(this.client.clientAddress, this.contractAddress, {unbond_gateway: {}}).catch((err) => this.handleRequestFailure(err))
const result = await this.client.executeContract(this.client.clientAddress, this.contractAddress, { unbond_gateway: {} }).catch((err) => this.handleRequestFailure(err))
console.log(`account ${this.client.clientAddress} unbonded gateway`);
return result;
} else {
@@ -425,7 +426,7 @@ export default class ValidatorClient {
async updateStateParams(newParams: StateParams): Promise<ExecuteResult> {
if (this.client instanceof NetClient) {
return await this.client.executeContract(this.client.clientAddress, this.contractAddress, {update_state_params: newParams}, "updating contract state").catch((err) => this.handleRequestFailure(err));
return await this.client.executeContract(this.client.clientAddress, this.contractAddress, { update_state_params: newParams }, "updating contract state").catch((err) => this.handleRequestFailure(err));
} else {
throw new Error("Tried to update state params with a query client")
}
@@ -443,7 +444,7 @@ export default class ValidatorClient {
let delegations: Delegation[] = [];
let response: PagedMixDelegationsResponse
let next: string | undefined = undefined;
for (;;) {
for (; ;) {
response = await this.client.getMixDelegations(this.contractAddress, mixIdentity, limit, next)
delegations = delegations.concat(response.delegations)
next = response.start_next_after
@@ -478,7 +479,7 @@ export default class ValidatorClient {
let delegations: Delegation[] = [];
let response: PagedGatewayDelegationsResponse
let next: string | undefined = undefined;
for (;;) {
for (; ;) {
response = await this.client.getGatewayDelegations(this.contractAddress, gatewayIdentity, limit, next)
delegations = delegations.concat(response.delegations)
next = response.start_next_after
@@ -531,7 +532,8 @@ export default class ValidatorClient {
const encoded = data.map(req => makeBankMsgSend(req.senderAddress, req.recipientAddress, req.transferAmount));
// the function to calculate fee for a single entry is not exposed...
const table = buildFeeTable(nymGasPrice(this.stakeDenom), {sendMultiple: nymGasLimits.send * data.length}, {sendMultiple: nymGasLimits.send * data.length})
console.log(`this.denom is ${this.denom}`);
const table = buildFeeTable(nymGasPrice(this.prefix), { sendMultiple: nymGasLimits.send * data.length }, { sendMultiple: nymGasLimits.send * data.length })
const fee = table.sendMultiple
const result = await this.client.signAndBroadcast(senderAddress, encoded, fee, memo)
if (isBroadcastTxFailure(result)) {
+8 -8
View File
@@ -16,7 +16,7 @@ import { ExecuteResult, InstantiateOptions, InstantiateResult, MigrateResult, Up
export interface INetClient {
clientAddress: string;
getBalance(address: string, stakeDenom: string): Promise<Coin | null>;
getBalance(address: string, denom: string): Promise<Coin | null>;
getMixNodes(contractAddress: string, limit: number, start_after?: string): Promise<PagedMixnodeResponse>;
getGateways(contractAddress: string, limit: number, start_after?: string): Promise<PagedGatewayResponse>;
getMixDelegations(contractAddress: string, mixIdentity: string, limit: number, start_after?: string): Promise<PagedMixDelegationsResponse>
@@ -57,10 +57,10 @@ export default class NetClient implements INetClient {
this.signerOptions = signerOptions;
}
public static async connect(wallet: DirectSecp256k1HdWallet, url: string, stakeDenom: string): Promise<INetClient> {
public static async connect(wallet: DirectSecp256k1HdWallet, url: string, prefix: string): Promise<INetClient> {
const [{ address }] = await wallet.getAccounts();
const signerOptions: SigningCosmWasmClientOptions = {
gasPrice: nymGasPrice(stakeDenom),
gasPrice: nymGasPrice(prefix),
gasLimits: nymGasLimits,
};
const client = await SigningCosmWasmClient.connectWithSigner(url, wallet, signerOptions);
@@ -91,7 +91,7 @@ export default class NetClient implements INetClient {
if (start_after == undefined) { // TODO: check if we can take this out, I'm not sure what will happen if we send an "undefined" so I'm playing it safe here.
return this.cosmClient.queryContractSmart(contractAddress, { get_mix_delegations: { mix_identity: mixIdentity, limit } });
} else {
return this.cosmClient.queryContractSmart(contractAddress, { get_mix_delegations: { mix_identity: mixIdentity, limit, start_after } });
return this.cosmClient.queryContractSmart(contractAddress, { get_mix_delegations: { mix_identity: mixIdentity, limit, start_after } });
}
}
@@ -103,7 +103,7 @@ export default class NetClient implements INetClient {
if (start_after == undefined) { // TODO: check if we can take this out, I'm not sure what will happen if we send an "undefined" so I'm playing it safe here.
return this.cosmClient.queryContractSmart(contractAddress, { get_gateway_delegations: { gateway_identity: gatewayIdentity, limit } });
} else {
return this.cosmClient.queryContractSmart(contractAddress, { get_gateway_delegations: { gateway_identity: gatewayIdentity, limit, start_after } });
return this.cosmClient.queryContractSmart(contractAddress, { get_gateway_delegations: { gateway_identity: gatewayIdentity, limit, start_after } });
}
}
@@ -119,12 +119,12 @@ export default class NetClient implements INetClient {
return this.cosmClient.queryContractSmart(contractAddress, { owns_gateway: { address } });
}
public getBalance(address: string, stakeDenom: string): Promise<Coin | null> {
return this.cosmClient.getBalance(address, stakeDenom);
public getBalance(address: string, denom: string): Promise<Coin | null> {
return this.cosmClient.getBalance(address, denom);
}
public getStateParams(contractAddress: string): Promise<StateParams> {
return this.cosmClient.queryContractSmart(contractAddress, { state_params: { } });
return this.cosmClient.queryContractSmart(contractAddress, { state_params: {} });
}
public executeContract(senderAddress: string, contractAddress: string, handleMsg: Record<string, unknown>, memo?: string, transferAmount?: readonly Coin[]): Promise<ExecuteResult> {
+5 -3
View File
@@ -7,7 +7,7 @@ export interface Options {
httpUrl: string;
networkId: string;
gasPrice: number;
bech32prefix: string;
prefix: string;
}
export const nymGasLimits: GasLimits<CosmWasmFeeTable> = {
@@ -19,13 +19,15 @@ export const nymGasLimits: GasLimits<CosmWasmFeeTable> = {
changeAdmin: 80_000,
};
export const nymGasPrice: (stakeDenom: string) => GasPrice = (stakeDenom: string) => GasPrice.fromString(`0.025${stakeDenom}`);
export function nymGasPrice(prefix: string): GasPrice {
return GasPrice.fromString(`0.025u${prefix}`); // TODO: ideally this ugly conversion shouldn't be hardcoded here.
};
export const defaultOptions: Options = {
httpUrl: "http://localhost:26657",
networkId: "nymnet",
gasPrice: 0.025,
bech32prefix: "hal",
prefix: "hal",
};
export const downloadWasm = async (url: string): Promise<Uint8Array> => {