From b4bb91e4fd038df317c80d5ba659f4025ed12b45 Mon Sep 17 00:00:00 2001 From: "Sewmina (server)" Date: Mon, 13 Jan 2025 01:02:32 +0800 Subject: [PATCH] idk --- package-lock.json | 400 ++++++++++++++++++++++++++++++- package.json | 5 +- src/app.js | 204 ++++++++++++++++ src/app.ts | 168 +++++++++++-- src/sol/IDL/tournaments.js | 2 + src/sol/IDL/tournaments.json | 447 ++++++++++++++++++++++++++++++++++ src/sol/IDL/tournaments.ts | 453 +++++++++++++++++++++++++++++++++++ src/sol/mhunt_reader.js | 69 ++++++ src/sol/mhunt_reader.ts | 66 +++++ src/sol/operator.js | 126 ++++++++++ src/sol/operator.ts | 148 ++++++++++++ src/sol/reader.js | 104 ++++++++ src/sol/reader.ts | 21 +- src/sol/shared.js | 23 ++ src/sol/shared.ts | 21 +- tsconfig.json | 119 ++++++++- 16 files changed, 2324 insertions(+), 52 deletions(-) create mode 100644 src/app.js create mode 100644 src/sol/IDL/tournaments.js create mode 100644 src/sol/IDL/tournaments.json create mode 100644 src/sol/IDL/tournaments.ts create mode 100644 src/sol/mhunt_reader.js create mode 100644 src/sol/mhunt_reader.ts create mode 100644 src/sol/operator.js create mode 100644 src/sol/reader.js create mode 100644 src/sol/shared.js diff --git a/package-lock.json b/package-lock.json index 832cace..63b0622 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,10 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@coral-xyz/anchor": "^0.30.1", + "@solana/spl-token": "^0.4.9", "@solana/web3.js": "^1.95.4", + "bs58": "^6.0.0", "dotenv": "^16.4.5", "express": "^4.17.1" }, @@ -34,6 +37,80 @@ "node": ">=6.9.0" } }, + "node_modules/@coral-xyz/anchor": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.30.1.tgz", + "integrity": "sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==", + "dependencies": { + "@coral-xyz/anchor-errors": "^0.30.1", + "@coral-xyz/borsh": "^0.30.1", + "@noble/hashes": "^1.3.1", + "@solana/web3.js": "^1.68.0", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^6.3.0", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "superstruct": "^0.15.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@coral-xyz/anchor-errors": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor-errors/-/anchor-errors-0.30.1.tgz", + "integrity": "sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@coral-xyz/anchor/node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@coral-xyz/anchor/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/@coral-xyz/anchor/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/@coral-xyz/anchor/node_modules/superstruct": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.15.5.tgz", + "integrity": "sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==" + }, + "node_modules/@coral-xyz/borsh": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.30.1.tgz", + "integrity": "sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.68.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -350,6 +427,180 @@ "node": ">=5.10" } }, + "node_modules/@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/codecs": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs/-/codecs-2.0.0-rc.1.tgz", + "integrity": "sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-data-structures": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/codecs-strings": "2.0.0-rc.1", + "@solana/options": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-core": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", + "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", + "dependencies": { + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-data-structures": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-rc.1.tgz", + "integrity": "sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-numbers": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", + "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-strings": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-2.0.0-rc.1.tgz", + "integrity": "sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "fastestsmallesttextencoderdecoder": "^1.0.22", + "typescript": ">=5" + } + }, + "node_modules/@solana/errors": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", + "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^12.1.0" + }, + "bin": { + "errors": "bin/cli.mjs" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/errors/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@solana/errors/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@solana/options": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/options/-/options-2.0.0-rc.1.tgz", + "integrity": "sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-data-structures": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/codecs-strings": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.4.9.tgz", + "integrity": "sha512-g3wbj4F4gq82YQlwqhPB0gHFXfgsC6UmyGMxtSLf/BozT/oKd59465DbnlUK8L8EcimKMavxsVAMoLcEdeCicg==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "@solana/spl-token-group": "^0.0.7", + "@solana/spl-token-metadata": "^0.1.6", + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, + "node_modules/@solana/spl-token-group": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@solana/spl-token-group/-/spl-token-group-0.0.7.tgz", + "integrity": "sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==", + "dependencies": { + "@solana/codecs": "2.0.0-rc.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, + "node_modules/@solana/spl-token-metadata": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@solana/spl-token-metadata/-/spl-token-metadata-0.1.6.tgz", + "integrity": "sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==", + "dependencies": { + "@solana/codecs": "2.0.0-rc.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, "node_modules/@solana/web3.js": { "version": "1.95.4", "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.95.4.tgz", @@ -373,6 +624,22 @@ "superstruct": "^2.0.2" } }, + "node_modules/@solana/web3.js/node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@solana/web3.js/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, "node_modules/@swc/helpers": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", @@ -922,13 +1189,9 @@ "license": "MIT" }, "node_modules/base-x": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", - "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.0.1" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.0.tgz", + "integrity": "sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -963,6 +1226,14 @@ "node": ">= 10.0.0" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -1010,6 +1281,22 @@ "text-encoding-utf-8": "^1.0.2" } }, + "node_modules/borsh/node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/borsh/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1035,12 +1322,11 @@ } }, "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "license": "MIT", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", + "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", "dependencies": { - "base-x": "^3.0.2" + "base-x": "^5.0.0" } }, "node_modules/buffer": { @@ -1067,6 +1353,14 @@ "ieee754": "^1.2.1" } }, + "node_modules/buffer-layout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", + "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==", + "engines": { + "node": ">=4.5" + } + }, "node_modules/bufferutil": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", @@ -1100,6 +1394,17 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1186,6 +1491,14 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1201,6 +1514,17 @@ "node": ">= 8" } }, + "node_modules/crypto-hash": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz", + "integrity": "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1244,6 +1568,15 @@ "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==", "license": "MIT" }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -1606,6 +1939,12 @@ "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", "license": "MIT" }, + "node_modules/fastestsmallesttextencoderdecoder": { + "version": "1.0.22", + "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", + "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", + "peer": true + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -2067,6 +2406,14 @@ "dev": true, "license": "MIT" }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -2183,6 +2530,15 @@ "node": ">= 0.6" } }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -2277,6 +2633,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2628,6 +2989,15 @@ "node": ">=8" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -2712,6 +3082,11 @@ "node": ">=0.6" } }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -2767,7 +3142,6 @@ "version": "5.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 74de34b..6b56508 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "main": "dist/app.js", "scripts": { - "start": "tsc && node dist/app.js", + "start": "tsc && node src/app.js", "lint": "eslint .", "test": "echo \"Error: no test specified\" && exit 1" }, @@ -20,7 +20,10 @@ "typescript-eslint": "^8.12.1" }, "dependencies": { + "@coral-xyz/anchor": "^0.30.1", + "@solana/spl-token": "^0.4.9", "@solana/web3.js": "^1.95.4", + "bs58": "^6.0.0", "dotenv": "^16.4.5", "express": "^4.17.1" } diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..4e34520 --- /dev/null +++ b/src/app.js @@ -0,0 +1,204 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const express_1 = __importDefault(require("express")); +const dotenv_1 = __importDefault(require("dotenv")); +dotenv_1.default.config(); +const reader_1 = require("./sol/reader"); +const operator_1 = require("./sol/operator"); +const mhunt_reader_1 = require("./sol/mhunt_reader"); +const app = (0, express_1.default)(); +const port = process.env.EXPRESS_PORT; +app.get("/status", (req, res) => { + res.status(200).json({ status: "Working" }); +}); +app.get("/getSolBalance", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { wallet } = req.query; + if (!wallet) { + res.status(403).json({ error: "Wallet should be present" }); + return; + } + const balance = yield (0, reader_1.GetSolBalance)(wallet.toString()); + const response = { + address: wallet, + balance: balance + }; + res.status(200).json(response); +})); +app.get("/getTicketsATA", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { wallet } = req.query; + if (!wallet) { + res.status(401).json({ error: "Wallet should be present" }); + return; + } + const tokenAddress = yield (0, reader_1.GetTicketsAccount)(wallet.toString()); + res.status(200).json({ ATA: tokenAddress }); +})); +app.get("/getTokenBalance", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { wallet } = req.query; + if (!wallet) { + res.status(401).json({ error: "Wallet should be present" }); + return; + } + try { + const tokenAddress = yield (0, reader_1.GetTokenAccount)(wallet.toString()); + console.log(`Token address for ${wallet} is ${tokenAddress}`); + const result = yield (0, reader_1.GetTokenBalanceByTA)(tokenAddress.toString()); + const balance = result < 0 ? 0 : result; + const response = { + tokenAccount: tokenAddress, + balance: balance + }; + res.status(200).json(response); + } + catch (_a) { + res.status(403).json({ error: "Something went wrong" }); + } +})); +app.get("/getTicketsBalance", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { wallet } = req.query; + if (!wallet) { + res.status(401).json({ error: "Wallet should be present" }); + return; + } + const tokenAddress = yield (0, reader_1.GetTicketsAccount)(wallet.toString()); + const result = yield (0, reader_1.GetTicketsBalanceByTA)(tokenAddress.toString()); + const balance = result < 0 ? 0 : result; + const response = { + tokenAccount: tokenAddress, + balance: balance + }; + res.status(200).json(response); +})); +app.get("/purchaseTicketsWithSk", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { amount } = req.query; + const { privateKey } = req.query; + if (!amount || !privateKey) { + res.status(401).json({ error: "Invalid Credentials" }); + return; + } + // await PurchaseTicket(privateKey.toString(), parseInt(amount.toString())); + res.status(200).json({ status: "Success" }); +})); +app.get("/purchaseTickets", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { amount, email, password } = req.query; + if (!email || !amount || !password) { + res.status(401).json({ error: "Invalid params" }); + return; + } + const authResult = yield fetch(`http://vps.playpoolstudios.com:20017/getKeypairWithPassword?email=${email}&password=${password}`); + const authResultJson = yield authResult.json(); + let privateKey = ""; + try { + privateKey = authResultJson['private_key']; + } + catch (_a) { + res.status(403).json({ status: "Failed", error: "Failed to authenticate" }); + } + try { + // const tx= await PurchaseTicket(privateKey.toString(), parseInt(amount.toString())); + // res.status(200).json({status:"Success",tx:tx}); + } + catch (_b) { + res.status(403).json({ status: "Failed", error: `Failed to purchase ${amount} tickets` }); + } +})); +app.get("/getJoinedTourneys", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { wallet } = req.query; + if (!wallet) { + res.status(402).json({ error: "Invalid params" }); + return; + } + const joinedTourneys = yield (0, mhunt_reader_1.GetJoinedTournaments)(wallet.toString()); + res.status(200).json(joinedTourneys); +})); +app.get("/getAllTournaments", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const tourneys = yield (0, mhunt_reader_1.GetTournaments)(); + res.status(200).json(tourneys); +})); +app.get("/previewJoinTournament", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { id, email, password } = req.query; + if (!email || !id || !password) { + res.status(401).json({ error: "Invalid params" }); + return; + } + const authResult = yield fetch(`http://vps.playpoolstudios.com:20017/getKeypairWithPassword?email=${email}&password=${password}`); + const authResultJson = yield authResult.json(); + let privateKey = ""; + try { + privateKey = authResultJson['private_key']; + } + catch (_a) { + res.status(403).json({ status: "Failed", error: "Failed to authenticate" }); + } + try { + const fee = yield (0, operator_1.previewJoinTournamentCost)(privateKey, parseInt(id.toString())); + res.status(200).json({ status: "Success", fee: fee }); + } + catch (e) { + console.log(e); + res.status(403).json({ status: "Failed", error: `Failed to preview Join tourney ${id}` }); + } +})); +app.get("/confirmJoinTournament", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { id, email, password } = req.query; + if (!email || !id || !password) { + res.status(401).json({ error: "Invalid params" }); + return; + } + const authResult = yield fetch(`http://vps.playpoolstudios.com:20017/getKeypairWithPassword?email=${email}&password=${password}`); + const authResultJson = yield authResult.json(); + let privateKey = ""; + try { + privateKey = authResultJson['private_key']; + } + catch (_a) { + res.status(403).json({ status: "Failed", error: "Failed to authenticate" }); + } + try { + const tx = yield (0, operator_1.JoinTournament)(privateKey, parseInt(id.toString())); + res.status(200).json({ status: "Success", tx: tx }); + } + catch (e) { + console.log(e); + res.status(403).json({ status: "Failed", error: `Failed to confirm Join tourney ${id}` }); + } +})); +app.get("/addNewTournament", (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { id, name, start_time, entry_fee, rewards1, rewards2, email, password } = req.query; + if (!email || !id || !password || !name || !entry_fee || !rewards1 || !rewards2 || !start_time) { + res.status(401).json({ error: "Invalid params" }); + return; + } + const authResult = yield fetch(`http://vps.playpoolstudios.com:20017/getKeypairWithPassword?email=${email}&password=${password}`); + const authResultJson = yield authResult.json(); + let privateKey = ""; + try { + privateKey = authResultJson['private_key']; + } + catch (_a) { + res.status(403).json({ status: "Failed", error: "Failed to authenticate" }); + } + try { + const tx = yield (0, operator_1.AddTournament)(privateKey, parseInt(id.toString()), name.toString(), start_time.toString(), parseInt(entry_fee.toString()), parseInt(rewards1.toString()), parseInt(rewards2.toString())); + res.status(200).json({ status: "Success", tx: tx }); + } + catch (e) { + console.log(e); + res.status(403).json({ status: "Failed", error: `Failed to add new tourney ${id}` }); + } +})); +app.listen(port, () => { + console.log(`Mhunt Solana Brdige listening to port ${port}`); +}); diff --git a/src/app.ts b/src/app.ts index e1aa0a9..31ed306 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,10 +1,13 @@ import express from 'express'; import dotenv from 'dotenv'; +dotenv.config(); + import { GetSolBalance, GetTicketsAccount, GetTicketsBalanceByTA, GetTokenAccount, GetTokenBalanceByTA } from "./sol/reader"; +import { AddTournament, JoinTournament, previewJoinTournamentCost } from './sol/operator'; +import { GetJoinedTournaments, GetTournaments } from './sol/mhunt_reader'; -dotenv.config(); const app = express(); const port = process.env.EXPRESS_PORT; @@ -18,7 +21,7 @@ app.get("/getSolBalance", async(req,res)=>{ if(!wallet){res.status(403).json({error:"Wallet should be present"}); return;} - const balance = await GetSolBalance(wallet); + const balance = await GetSolBalance(wallet.toString()); const response = { address: wallet, @@ -28,28 +31,41 @@ app.get("/getSolBalance", async(req,res)=>{ res.status(200).json(response); }) +app.get("/getTicketsATA", async(req,res)=>{ + const{ wallet } = req.query; + if(!wallet){res.status(401).json({error:"Wallet should be present"}); return;} + + const tokenAddress = await GetTicketsAccount(wallet.toString()); + + res.status(200).json({ATA:tokenAddress}); +}) + app.get("/getTokenBalance", async(req,res)=>{ const{ wallet } = req.query; - if(!wallet){res.status(403).json({error:"Wallet should be present"}); return;} + if(!wallet){res.status(401).json({error:"Wallet should be present"}); return;} + try{ + const tokenAddress = await GetTokenAccount(wallet.toString()); + console.log(`Token address for ${wallet} is ${tokenAddress}`); + const result = await GetTokenBalanceByTA(tokenAddress!.toString()); + const balance = result <0 ? 0 : result; - const tokenAddress = await GetTokenAccount(wallet); - const result = await GetTokenBalanceByTA(tokenAddress); - const balance = result <0 ? 0 : result; + const response = { + tokenAccount:tokenAddress, + balance:balance + } - const response = { - tokenAccount:tokenAddress, - balance:balance + res.status(200).json(response); + }catch{ + res.status(403).json({error:"Something went wrong"}); } - - res.status(200).json(response); }) app.get("/getTicketsBalance", async(req,res)=>{ const{ wallet } = req.query; - if(!wallet){res.status(403).json({error:"Wallet should be present"}); return;} + if(!wallet){res.status(401).json({error:"Wallet should be present"}); return;} - const tokenAddress = await GetTicketsAccount(wallet); - const result = await GetTicketsBalanceByTA(tokenAddress); + const tokenAddress = await GetTicketsAccount(wallet.toString()); + const result = await GetTicketsBalanceByTA(tokenAddress!.toString()); const balance = result <0 ? 0 : result; const response = { @@ -60,10 +76,128 @@ app.get("/getTicketsBalance", async(req,res)=>{ res.status(200).json(response); }) -app.get("/purchaseTickets", async(req,res)=>{ +app.get("/purchaseTicketsWithSk", async(req,res)=>{ const {amount} = req.query; - if(!amount){ - res.status(403).json({error:"Enter an amount"}); return; + const {privateKey} = req.query; + + if(!amount || !privateKey){ + res.status(401).json({error:"Invalid Credentials"}); return; + } + + // await PurchaseTicket(privateKey.toString(), parseInt(amount.toString())); + + res.status(200).json({status:"Success"}) +}) + +app.get("/purchaseTickets", async(req,res)=>{ + const {amount,email, password} = req.query; + + if(!email || !amount || !password){ + res.status(401).json({error:"Invalid params"}); return; + } + + const authResult = await fetch(`http://vps.playpoolstudios.com:20017/getKeypairWithPassword?email=${email}&password=${password}`); + const authResultJson = await authResult.json(); + let privateKey = ""; + try{ + privateKey = authResultJson['private_key']; + }catch{ + res.status(403).json({status:"Failed",error:"Failed to authenticate"}); + } + try{ + // const tx= await PurchaseTicket(privateKey.toString(), parseInt(amount.toString())); + // res.status(200).json({status:"Success",tx:tx}); + }catch{ + res.status(403).json({status:"Failed",error:`Failed to purchase ${amount} tickets`}); + } +}) + +app.get("/getJoinedTourneys", async(req,res)=>{ + const {wallet} = req.query; + + if(!wallet){ + res.status(402).json({error: "Invalid params"}); return; + } + + const joinedTourneys = await GetJoinedTournaments(wallet.toString()); + + res.status(200).json(joinedTourneys); +}) + +app.get("/getAllTournaments", async(req,res)=>{ + const tourneys = await GetTournaments(); + + res.status(200).json(tourneys); +}) + +app.get("/previewJoinTournament", async(req,res)=>{ + const {id,email, password} = req.query; + + if(!email || !id || !password){ + res.status(401).json({error:"Invalid params"}); return; + } + const authResult = await fetch(`http://vps.playpoolstudios.com:20017/getKeypairWithPassword?email=${email}&password=${password}`); + const authResultJson = await authResult.json(); + let privateKey = ""; + try{ + privateKey = authResultJson['private_key']; + }catch{ + res.status(403).json({status:"Failed",error:"Failed to authenticate"}); + } + try{ + const fee= await previewJoinTournamentCost(privateKey, parseInt(id.toString())); + res.status(200).json({status:"Success",fee:fee}); + }catch(e){ + console.log(e); + res.status(403).json({status:"Failed",error:`Failed to preview Join tourney ${id}`}); + } +}) + +app.get("/confirmJoinTournament", async(req,res)=>{ + const {id,email, password} = req.query; + + if(!email || !id || !password){ + res.status(401).json({error:"Invalid params"}); return; + } + const authResult = await fetch(`http://vps.playpoolstudios.com:20017/getKeypairWithPassword?email=${email}&password=${password}`); + const authResultJson = await authResult.json(); + let privateKey = ""; + try{ + privateKey = authResultJson['private_key']; + }catch{ + res.status(403).json({status:"Failed",error:"Failed to authenticate"}); + } + try{ + const tx= await JoinTournament(privateKey, parseInt(id.toString())); + res.status(200).json({status:"Success",tx:tx}); + }catch(e){ + console.log(e); + res.status(403).json({status:"Failed",error:`Failed to confirm Join tourney ${id}`}); + } +}) + +app.get("/addNewTournament", async(req,res)=>{ + const {id,name,start_time,entry_fee,rewards1,rewards2 ,email, password} = req.query; + + if(!email || !id || !password || !name || !entry_fee || !rewards1 || !rewards2 || !start_time){ + res.status(401).json({error:"Invalid params"}); return; + } + const authResult = await fetch(`http://vps.playpoolstudios.com:20017/getKeypairWithPassword?email=${email}&password=${password}`); + const authResultJson = await authResult.json(); + let privateKey = ""; + try{ + privateKey = authResultJson['private_key']; + }catch{ + res.status(403).json({status:"Failed",error:"Failed to authenticate"}); + } + + + try{ + const tx= await AddTournament(privateKey,parseInt(id.toString()), name.toString(), start_time.toString(), parseInt(entry_fee.toString()), parseInt(rewards1.toString()), parseInt(rewards2.toString())); + res.status(200).json({status:"Success",tx:tx}); + }catch(e){ + console.log(e); + res.status(403).json({status:"Failed",error:`Failed to add new tourney ${id}`}); } }) diff --git a/src/sol/IDL/tournaments.js b/src/sol/IDL/tournaments.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/src/sol/IDL/tournaments.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/src/sol/IDL/tournaments.json b/src/sol/IDL/tournaments.json new file mode 100644 index 0000000..2b5c9e9 --- /dev/null +++ b/src/sol/IDL/tournaments.json @@ -0,0 +1,447 @@ +{ + "address": "38GxGJCSGsRRx9Y55aErAavNZMagaAiyddBMPtmXiNiV", + "metadata": { + "name": "tournaments", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Created with Anchor" + }, + "instructions": [ + { + "name": "add_tournament", + "discriminator": [ + 86, + 126, + 171, + 66, + 224, + 148, + 167, + 201 + ], + "accounts": [ + { + "name": "payer", + "writable": true, + "signer": true + }, + { + "name": "tournament_account", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 116, + 111, + 117, + 114, + 110, + 97, + 109, + 101, + 110, + 116 + ] + }, + { + "kind": "arg", + "path": "id" + } + ] + } + }, + { + "name": "tournament_vault", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 116, + 111, + 117, + 114, + 110, + 97, + 109, + 101, + 110, + 116, + 95, + 118, + 97, + 117, + 108, + 116 + ] + }, + { + "kind": "arg", + "path": "id" + } + ] + } + }, + { + "name": "data_registry", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 115, + 97, + 108, + 101, + 115, + 95, + 114, + 101, + 103 + ] + } + ] + } + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "id", + "type": "u64" + }, + { + "name": "entry_fee", + "type": "u64" + }, + { + "name": "start_time", + "type": "string" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "reward_1", + "type": "u64" + }, + { + "name": "reward_2", + "type": "u64" + } + ] + }, + { + "name": "initialize", + "discriminator": [ + 175, + 175, + 109, + 31, + 13, + 152, + 155, + 237 + ], + "accounts": [ + { + "name": "signer", + "writable": true, + "signer": true + }, + { + "name": "data_registry", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 115, + 97, + 108, + 101, + 115, + 95, + 114, + 101, + 103 + ] + } + ] + } + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [] + }, + { + "name": "join_tournament", + "discriminator": [ + 77, + 21, + 212, + 206, + 77, + 82, + 124, + 31 + ], + "accounts": [ + { + "name": "user", + "writable": true, + "signer": true + }, + { + "name": "tournament_account", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 116, + 111, + 117, + 114, + 110, + 97, + 109, + 101, + 110, + 116 + ] + }, + { + "kind": "arg", + "path": "id" + } + ] + } + }, + { + "name": "tournament_vault", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 116, + 111, + 117, + 114, + 110, + 97, + 109, + 101, + 110, + 116, + 95, + 118, + 97, + 117, + 108, + 116 + ] + }, + { + "kind": "arg", + "path": "id" + } + ] + } + }, + { + "name": "data_registry", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 115, + 97, + 108, + 101, + 115, + 95, + 114, + 101, + 103 + ] + } + ] + } + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "id", + "type": "u64" + } + ] + } + ], + "accounts": [ + { + "name": "DataRegistry", + "discriminator": [ + 169, + 50, + 35, + 17, + 11, + 106, + 49, + 193 + ] + }, + { + "name": "Tournament", + "discriminator": [ + 175, + 139, + 119, + 242, + 115, + 194, + 57, + 92 + ] + } + ], + "errors": [ + { + "code": 6000, + "name": "CustomError", + "msg": "Custom error message" + }, + { + "code": 6001, + "name": "InsufficientFunds", + "msg": "Insufficient funds to purchase a ticket, Recharge your wallet and try again" + }, + { + "code": 6002, + "name": "Unauthorized", + "msg": "Only the owner can perform this action" + }, + { + "code": 6003, + "name": "ExistingTournament", + "msg": "This tournament ID already exists, use a different one" + } + ], + "types": [ + { + "name": "DataRegistry", + "type": { + "kind": "struct", + "fields": [ + { + "name": "authority", + "type": "pubkey" + }, + { + "name": "tournament_ids", + "type": { + "vec": "u64" + } + } + ] + } + }, + { + "name": "Tournament", + "type": { + "kind": "struct", + "fields": [ + { + "name": "id", + "type": "u64" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "participants", + "type": { + "vec": "pubkey" + } + }, + { + "name": "entry_fee", + "type": "u64" + }, + { + "name": "start_time", + "type": "string" + }, + { + "name": "rewards_1", + "type": "u64" + }, + { + "name": "rewards_2", + "type": "u64" + } + ] + } + } + ], + "constants": [ + { + "name": "DATA_REGISTRY_SEED", + "type": { + "array": [ + "u8", + 9 + ] + }, + "value": "[115, 97, 108, 101, 115, 95, 114, 101, 103]" + }, + { + "name": "ID", + "type": "string", + "value": "\"\"" + }, + { + "name": "TOURNAMENT_SEED", + "type": { + "array": [ + "u8", + 10 + ] + }, + "value": "[116, 111, 117, 114, 110, 97, 109, 101, 110, 116]" + }, + { + "name": "TOURNAMENT_VAULT_SEED", + "type": { + "array": [ + "u8", + 16 + ] + }, + "value": "[116, 111, 117, 114, 110, 97, 109, 101, 110, 116, 95, 118, 97, 117, 108, 116]" + } + ] +} \ No newline at end of file diff --git a/src/sol/IDL/tournaments.ts b/src/sol/IDL/tournaments.ts new file mode 100644 index 0000000..1f7ca85 --- /dev/null +++ b/src/sol/IDL/tournaments.ts @@ -0,0 +1,453 @@ +/** + * Program IDL in camelCase format in order to be used in JS/TS. + * + * Note that this is only a type helper and is not the actual IDL. The original + * IDL can be found at `target/idl/tournaments.json`. + */ + export type Tournaments = { + "address": "38GxGJCSGsRRx9Y55aErAavNZMagaAiyddBMPtmXiNiV", + "metadata": { + "name": "tournaments", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Created with Anchor" + }, + "instructions": [ + { + "name": "addTournament", + "discriminator": [ + 86, + 126, + 171, + 66, + 224, + 148, + 167, + 201 + ], + "accounts": [ + { + "name": "payer", + "writable": true, + "signer": true + }, + { + "name": "tournamentAccount", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 116, + 111, + 117, + 114, + 110, + 97, + 109, + 101, + 110, + 116 + ] + }, + { + "kind": "arg", + "path": "id" + } + ] + } + }, + { + "name": "tournamentVault", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 116, + 111, + 117, + 114, + 110, + 97, + 109, + 101, + 110, + 116, + 95, + 118, + 97, + 117, + 108, + 116 + ] + }, + { + "kind": "arg", + "path": "id" + } + ] + } + }, + { + "name": "dataRegistry", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 115, + 97, + 108, + 101, + 115, + 95, + 114, + 101, + 103 + ] + } + ] + } + }, + { + "name": "systemProgram", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "id", + "type": "u64" + }, + { + "name": "entryFee", + "type": "u64" + }, + { + "name": "startTime", + "type": "string" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "reward1", + "type": "u64" + }, + { + "name": "reward2", + "type": "u64" + } + ] + }, + { + "name": "initialize", + "discriminator": [ + 175, + 175, + 109, + 31, + 13, + 152, + 155, + 237 + ], + "accounts": [ + { + "name": "signer", + "writable": true, + "signer": true + }, + { + "name": "dataRegistry", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 115, + 97, + 108, + 101, + 115, + 95, + 114, + 101, + 103 + ] + } + ] + } + }, + { + "name": "systemProgram", + "address": "11111111111111111111111111111111" + } + ], + "args": [] + }, + { + "name": "joinTournament", + "discriminator": [ + 77, + 21, + 212, + 206, + 77, + 82, + 124, + 31 + ], + "accounts": [ + { + "name": "user", + "writable": true, + "signer": true + }, + { + "name": "tournamentAccount", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 116, + 111, + 117, + 114, + 110, + 97, + 109, + 101, + 110, + 116 + ] + }, + { + "kind": "arg", + "path": "id" + } + ] + } + }, + { + "name": "tournamentVault", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 116, + 111, + 117, + 114, + 110, + 97, + 109, + 101, + 110, + 116, + 95, + 118, + 97, + 117, + 108, + 116 + ] + }, + { + "kind": "arg", + "path": "id" + } + ] + } + }, + { + "name": "dataRegistry", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 115, + 97, + 108, + 101, + 115, + 95, + 114, + 101, + 103 + ] + } + ] + } + }, + { + "name": "systemProgram", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "id", + "type": "u64" + } + ] + } + ], + "accounts": [ + { + "name": "dataRegistry", + "discriminator": [ + 169, + 50, + 35, + 17, + 11, + 106, + 49, + 193 + ] + }, + { + "name": "tournament", + "discriminator": [ + 175, + 139, + 119, + 242, + 115, + 194, + 57, + 92 + ] + } + ], + "errors": [ + { + "code": 6000, + "name": "customError", + "msg": "Custom error message" + }, + { + "code": 6001, + "name": "insufficientFunds", + "msg": "Insufficient funds to purchase a ticket, Recharge your wallet and try again" + }, + { + "code": 6002, + "name": "unauthorized", + "msg": "Only the owner can perform this action" + }, + { + "code": 6003, + "name": "existingTournament", + "msg": "This tournament ID already exists, use a different one" + } + ], + "types": [ + { + "name": "dataRegistry", + "type": { + "kind": "struct", + "fields": [ + { + "name": "authority", + "type": "pubkey" + }, + { + "name": "tournamentIds", + "type": { + "vec": "u64" + } + } + ] + } + }, + { + "name": "tournament", + "type": { + "kind": "struct", + "fields": [ + { + "name": "id", + "type": "u64" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "participants", + "type": { + "vec": "pubkey" + } + }, + { + "name": "entryFee", + "type": "u64" + }, + { + "name": "startTime", + "type": "string" + }, + { + "name": "rewards1", + "type": "u64" + }, + { + "name": "rewards2", + "type": "u64" + } + ] + } + } + ], + "constants": [ + { + "name": "dataRegistrySeed", + "type": { + "array": [ + "u8", + 9 + ] + }, + "value": "[115, 97, 108, 101, 115, 95, 114, 101, 103]" + }, + { + "name": "id", + "type": "string", + "value": "\"\"" + }, + { + "name": "tournamentSeed", + "type": { + "array": [ + "u8", + 10 + ] + }, + "value": "[116, 111, 117, 114, 110, 97, 109, 101, 110, 116]" + }, + { + "name": "tournamentVaultSeed", + "type": { + "array": [ + "u8", + 16 + ] + }, + "value": "[116, 111, 117, 114, 110, 97, 109, 101, 110, 116, 95, 118, 97, 117, 108, 116]" + } + ] +}; diff --git a/src/sol/mhunt_reader.js b/src/sol/mhunt_reader.js new file mode 100644 index 0000000..c2a1458 --- /dev/null +++ b/src/sol/mhunt_reader.js @@ -0,0 +1,69 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetJoinedTournaments = GetJoinedTournaments; +exports.GetTournaments = GetTournaments; +exports.GetTournamentData = GetTournamentData; +const web3_js_1 = require("@solana/web3.js"); +const shared_1 = require("./shared"); +const IDL = require('./IDL/tournaments.json'); +function GetJoinedTournaments(_pubkey) { + return __awaiter(this, void 0, void 0, function* () { + const pubkey = new web3_js_1.PublicKey(_pubkey); + const [sellers_reg_pda] = yield web3_js_1.PublicKey.findProgramAddress([Buffer.from("sales_reg")], shared_1.PROGRAM.programId); + console.log(`Sellers Reg PDA: ${sellers_reg_pda}`); + const data_reg = yield shared_1.PROGRAM.account.dataRegistry.fetch(sellers_reg_pda); + const tourneyIds = data_reg.tournamentIds; + let joinedTourneys = []; + console.log(`Checking ${tourneyIds.length} tourneys`); + for (let i = 0; i < tourneyIds.length; i++) { + const tourneyAcc = yield GetTournamentData(tourneyIds[i]); + console.log(JSON.stringify(tourneyAcc)); + tourneyAcc.participants.forEach((participant) => { + if (participant.toBase58() == _pubkey) { + joinedTourneys.push(tourneyAcc); + } + }); + } + console.log(`${_pubkey} is in ${joinedTourneys.length} tourneys`); + return joinedTourneys; + }); +} +function GetTournaments() { + return __awaiter(this, void 0, void 0, function* () { + const [sellers_reg_pda] = yield web3_js_1.PublicKey.findProgramAddress([Buffer.from("sales_reg")], shared_1.PROGRAM.programId); + console.log(`Sellers Reg PDA: ${sellers_reg_pda}`); + const data_reg = yield shared_1.PROGRAM.account.dataRegistry.fetch(sellers_reg_pda); + const tourneyIds = data_reg.tournamentIds; + let tourneys = []; + for (let i = 0; i < tourneyIds.length; i++) { + const tourneyAcc = yield GetTournamentData(tourneyIds[i]); + tourneys.push({ + id: tourneyAcc.id.toString(), + name: tourneyAcc.name, + startTime: tourneyAcc.startTime, + participants: tourneyAcc.participants, + entryFee: tourneyAcc.entryFee.toString(), + rewards1: tourneyAcc.rewards1.toString(), + rewards2: tourneyAcc.rewards2.toString() + }); + } + return tourneys; + }); +} +function GetTournamentData(tourneyId) { + return __awaiter(this, void 0, void 0, function* () { + const tourneyIdBuffer = tourneyId.toArrayLike(Buffer, 'le', 8); + const [tourneyPda] = yield web3_js_1.PublicKey.findProgramAddressSync([shared_1.TOURNAMENT_SEED, tourneyIdBuffer], shared_1.PROGRAM.programId); + const tourneyAcc = yield shared_1.PROGRAM.account.tournament.fetch(tourneyPda); + return tourneyAcc; + }); +} diff --git a/src/sol/mhunt_reader.ts b/src/sol/mhunt_reader.ts new file mode 100644 index 0000000..efcbd93 --- /dev/null +++ b/src/sol/mhunt_reader.ts @@ -0,0 +1,66 @@ +import { PublicKey, Connection, Keypair, Transaction } from '@solana/web3.js'; +import {createAssociatedTokenAccount, createAssociatedTokenAccountInstruction, getAssociatedTokenAddress} from '@solana/spl-token'; +import {ASSOCIATED_TOKEN_PROGRAM_ID, connection, PROGRAM, TICKET_PRICE, TICKETS_MINT, TOKEN_PROGRAM_ID, TOKENS_MINT, TOURNAMENT_SEED} from './shared'; + +import { Tournaments } from "./IDL/tournaments"; +import {AnchorProvider, BN, Program, Wallet} from '@coral-xyz/anchor'; +import bs58 from "bs58"; +const IDL = require('./IDL/tournaments.json'); + +export async function GetJoinedTournaments(_pubkey:string){ + const pubkey = new PublicKey(_pubkey); + const [sellers_reg_pda] = await PublicKey.findProgramAddress([Buffer.from("sales_reg")], PROGRAM.programId); + console.log(`Sellers Reg PDA: ${sellers_reg_pda}`); + + const data_reg = await PROGRAM.account.dataRegistry.fetch(sellers_reg_pda); + const tourneyIds = data_reg.tournamentIds; + + let joinedTourneys: { id: BN; participants: PublicKey[]; entryFee: BN; startTime: string; }[] = []; + console.log(`Checking ${tourneyIds.length} tourneys`); + for(let i =0; i < tourneyIds.length; i++){ + const tourneyAcc = await GetTournamentData(tourneyIds[i]); + console.log(JSON.stringify(tourneyAcc)); + + tourneyAcc.participants.forEach((participant)=>{ + if(participant.toBase58() == _pubkey){ + joinedTourneys.push(tourneyAcc); + } + }) + } + + console.log(`${_pubkey} is in ${joinedTourneys.length} tourneys`); + + return joinedTourneys; +} + +export async function GetTournaments(){ + const [sellers_reg_pda] = await PublicKey.findProgramAddress([Buffer.from("sales_reg")], PROGRAM.programId); + console.log(`Sellers Reg PDA: ${sellers_reg_pda}`); + + const data_reg = await PROGRAM.account.dataRegistry.fetch(sellers_reg_pda); + const tourneyIds = data_reg.tournamentIds; + + let tourneys = []; + for(let i =0; i < tourneyIds.length; i++){ + const tourneyAcc = await GetTournamentData(tourneyIds[i]); + tourneys.push({ + id:tourneyAcc.id.toString(), + name:tourneyAcc.name, + startTime: tourneyAcc.startTime, + participants:tourneyAcc.participants, + entryFee:tourneyAcc.entryFee.toString(), + rewards1:tourneyAcc.rewards1.toString(), + rewards2:tourneyAcc.rewards2.toString() + }); + } + return tourneys; +} + + +export async function GetTournamentData(tourneyId:BN){ + const tourneyIdBuffer = tourneyId.toArrayLike(Buffer,'le',8); + const [tourneyPda] = await PublicKey.findProgramAddressSync([TOURNAMENT_SEED, tourneyIdBuffer], PROGRAM.programId); + + const tourneyAcc = await PROGRAM.account.tournament.fetch(tourneyPda); + return tourneyAcc; +} \ No newline at end of file diff --git a/src/sol/operator.js b/src/sol/operator.js new file mode 100644 index 0000000..52e1919 --- /dev/null +++ b/src/sol/operator.js @@ -0,0 +1,126 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.previewJoinTournamentCost = previewJoinTournamentCost; +exports.JoinTournament = JoinTournament; +exports.AddTournament = AddTournament; +const web3_js_1 = require("@solana/web3.js"); +const shared_1 = require("./shared"); +const anchor_1 = require("@coral-xyz/anchor"); +const bs58_1 = __importDefault(require("bs58")); +const rpc_1 = require("@coral-xyz/anchor/dist/cjs/utils/rpc"); +function previewJoinTournamentCost(privateKey, id) { + return __awaiter(this, void 0, void 0, function* () { + var _a; + const keypair = web3_js_1.Keypair.fromSecretKey(bs58_1.default.decode(privateKey)); + const provider = new anchor_1.AnchorProvider(shared_1.connection, new anchor_1.Wallet(keypair)); + const program = new anchor_1.Program(shared_1.IDL, provider); + const tourneyId = new anchor_1.BN(id); + const tourneyIdBuffer = tourneyId.toArrayLike(Buffer, 'le', 8); + const [tourneyPda] = yield web3_js_1.PublicKey.findProgramAddressSync([shared_1.TOURNAMENT_SEED, tourneyIdBuffer], program.programId); + const tourneyAcc = yield program.account.tournament.fetch(tourneyPda); + // Simulate the transaction to preview cost + const transaction = new web3_js_1.Transaction().add(yield program.methods.joinTournament(tourneyId).instruction()); + transaction.recentBlockhash = (yield shared_1.connection.getLatestBlockhash('finalized')).blockhash; + transaction.feePayer = keypair.publicKey; + const { value } = yield (0, rpc_1.simulateTransaction)(shared_1.connection, transaction); + // The 'value' contains the fee and log messages; you can access the fee estimate here + if (value.err) { + console.error("Simulation error:", value.err); + return; + } + // Estimate the fee using getFeeForMessage + const message = transaction.compileMessage(); + const feeEstimate = yield shared_1.connection.getFeeForMessage(message); + if (feeEstimate) { + console.log(`Estimated transaction fee: ${feeEstimate} lamports`); + const entryFee = tourneyAcc.entryFee; + return ((_a = feeEstimate.value) !== null && _a !== void 0 ? _a : 0) + parseInt(entryFee.toString()); + } + else { + console.error("Could not retrieve fee estimate."); + return null; + } + }); +} +function JoinTournament(privateKey, id) { + return __awaiter(this, void 0, void 0, function* () { + const keypair = web3_js_1.Keypair.fromSecretKey(bs58_1.default.decode(privateKey)); + const provider = new anchor_1.AnchorProvider(shared_1.connection, new anchor_1.Wallet(keypair)); + const program = new anchor_1.Program(shared_1.IDL, provider); + const solBalance = yield shared_1.connection.getBalance(keypair.publicKey); + const tourneyId = new anchor_1.BN(id); + const tourneyIdBuffer = tourneyId.toArrayLike(Buffer, 'le', 8); + const [tourneyPda] = yield web3_js_1.PublicKey.findProgramAddressSync([shared_1.TOURNAMENT_SEED, tourneyIdBuffer], program.programId); + const tourneyAcc = yield program.account.tournament.fetch(tourneyPda); + const tx = yield program.methods.joinTournament(tourneyId).rpc(); + return tx; + }); +} +function AddTournament(privateKey, id, name, start_time, entry_fee_lamports, rewards1, rewards2) { + return __awaiter(this, void 0, void 0, function* () { + const keypair = web3_js_1.Keypair.fromSecretKey(bs58_1.default.decode(privateKey)); + const provider = new anchor_1.AnchorProvider(shared_1.connection, new anchor_1.Wallet(keypair)); + const program = new anchor_1.Program(shared_1.IDL, provider); + const tx = yield program.methods.addTournament(new anchor_1.BN(id), new anchor_1.BN(entry_fee_lamports), start_time, name, new anchor_1.BN(rewards1), new anchor_1.BN(rewards2)).rpc(); + return tx; + }); +} +// export async function PurchaseTicket(privateKey:string, amount:number){ +// const totalPrice = amount * TICKET_PRICE; +// if(solBalance < totalPrice){ +// console.log(`${keypair.publicKey} tried to buy ${amount} tickets (${totalPrice} SOL). But they had only ${solBalance}`); +// return false; +// } +// const [buyerAta] = await PublicKey.findProgramAddress([keypair.publicKey.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), TICKETS_MINT.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID); +// let ticketsBalanceBefore = 0; +// console.log(`buyers ATA is: ${buyerAta.toBase58()}`); +// try{ +// ticketsBalanceBefore = (await connection.getTokenAccountBalance(buyerAta)).value.uiAmount ?? 0; +// console.log(`buyer has ${ticketsBalanceBefore} tickets already`); +// }catch{ +// const buyerAta = await getAssociatedTokenAddress(TICKETS_MINT, keypair.publicKey, false, TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID); +// console.log("Buyer doesn't even has an ATA for this token, creating one"); +// const createAtaInstruction = createAssociatedTokenAccountInstruction( +// keypair.publicKey, // Payer +// buyerAta, // Associated Token Account to create +// keypair.publicKey, // Owner of the account +// TICKETS_MINT, // Token mint address +// TOKEN_PROGRAM_ID, // Token program ID +// ASSOCIATED_TOKEN_PROGRAM_ID // Associated token program ID +// ); +// const transaction = new Transaction().add(createAtaInstruction); +// await provider.sendAndConfirm(transaction, [keypair]); +// console.log(`Created ATA: ${buyerAta.toBase58()}`); +// console.log(`Buyer ATA Created: ${buyerAta}`); +// } +// const [sellers_reg_pda] = await PublicKey.findProgramAddress([Buffer.from("sales_reg")], program.programId); +// console.log(`Sellers Reg PDA: ${sellers_reg_pda}`); +// const seller = new PublicKey('cocD4r4yNpHxPq7CzUebxEMyLki3X4d2Y3HcTX5ptUc'); +// // Make the transaction to purchase tickets +// try{ +// console.log(`Purchasing ${amount} tickets from ${seller.toBase58()}`); +// const tx = await program.methods.purchaseTickets(new BN(1)).accounts({ +// seller:seller, +// mint: TICKETS_MINT, +// tokenProgram: TOKEN_PROGRAM_ID, +// }).rpc(); +// console.log(`Ticket purchase transaction successful: ${tx}`); +// return tx; +// }catch(e){ +// console.log("Failed to purchase tickets") +// console.log(e); +// return null; +// } +// } diff --git a/src/sol/operator.ts b/src/sol/operator.ts index e69de29..9e4c2d8 100644 --- a/src/sol/operator.ts +++ b/src/sol/operator.ts @@ -0,0 +1,148 @@ +import { PublicKey, Connection, Keypair, Transaction } from '@solana/web3.js'; +import {createAssociatedTokenAccount, createAssociatedTokenAccountInstruction, getAssociatedTokenAddress} from '@solana/spl-token'; +import {ASSOCIATED_TOKEN_PROGRAM_ID, connection, IDL, PROGRAM, TICKET_PRICE, TICKETS_MINT, TOKEN_PROGRAM_ID, TOKENS_MINT, TOURNAMENT_SEED} from './shared'; + +import { Tournaments } from "./IDL/tournaments"; +import {AnchorProvider, BN, Program, Wallet} from '@coral-xyz/anchor'; +import bs58 from "bs58"; +import { simulateTransaction } from '@coral-xyz/anchor/dist/cjs/utils/rpc'; + +export async function previewJoinTournamentCost(privateKey: string, id: number) { + const keypair = Keypair.fromSecretKey( + bs58.decode(privateKey) + ); + const provider = new AnchorProvider(connection, new Wallet(keypair)); + const program = new Program(IDL, provider); + + const tourneyId = new BN(id); + const tourneyIdBuffer = tourneyId.toArrayLike(Buffer, 'le', 8); + const [tourneyPda] = await PublicKey.findProgramAddressSync([TOURNAMENT_SEED, tourneyIdBuffer], program.programId); + const tourneyAcc = await program.account.tournament.fetch(tourneyPda); + // Simulate the transaction to preview cost + const transaction = new Transaction().add( + await program.methods.joinTournament(tourneyId).instruction() + ); + transaction.recentBlockhash = (await connection.getLatestBlockhash('finalized')).blockhash; + transaction.feePayer = keypair.publicKey; + + const { value } = await simulateTransaction(connection,transaction); + + // The 'value' contains the fee and log messages; you can access the fee estimate here + if (value.err) { + console.error("Simulation error:", value.err); + return; + } + + // Estimate the fee using getFeeForMessage + const message = transaction.compileMessage(); + const feeEstimate = await connection.getFeeForMessage(message); + + if (feeEstimate) { + console.log(`Estimated transaction fee: ${feeEstimate} lamports`); + + const entryFee = tourneyAcc.entryFee; + return (feeEstimate.value ?? 0) + parseInt(entryFee.toString()); + } else { + console.error("Could not retrieve fee estimate."); + return null; + } +} + +export async function JoinTournament(privateKey:string, id:number){ + const keypair = Keypair.fromSecretKey( + bs58.decode(privateKey) + ); + const provider = new AnchorProvider(connection, new Wallet(keypair)); + const program = new Program(IDL, provider); + + const solBalance = await connection.getBalance(keypair.publicKey); + + const tourneyId = new BN(id); + + const tourneyIdBuffer = tourneyId.toArrayLike(Buffer,'le',8); + const [tourneyPda] = await PublicKey.findProgramAddressSync([TOURNAMENT_SEED, tourneyIdBuffer], program.programId); + + const tourneyAcc = await program.account.tournament.fetch(tourneyPda); + + const tx= await program.methods.joinTournament(tourneyId).rpc(); + + return tx; +} + + +export async function AddTournament(privateKey:string,id:number, name:string, start_time:string, entry_fee_lamports:number, rewards1:number, rewards2:number){ + const keypair = Keypair.fromSecretKey( + bs58.decode(privateKey) + ); + const provider = new AnchorProvider(connection, new Wallet(keypair)); + const program = new Program(IDL, provider); + + const tx = await program.methods.addTournament( + new BN(id), + new BN(entry_fee_lamports), + start_time, + name, + new BN(rewards1), + new BN(rewards2) + ).rpc(); + + return tx; +} + +// export async function PurchaseTicket(privateKey:string, amount:number){ + +// const totalPrice = amount * TICKET_PRICE; +// if(solBalance < totalPrice){ +// console.log(`${keypair.publicKey} tried to buy ${amount} tickets (${totalPrice} SOL). But they had only ${solBalance}`); +// return false; +// } + +// const [buyerAta] = await PublicKey.findProgramAddress([keypair.publicKey.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), TICKETS_MINT.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID); +// let ticketsBalanceBefore = 0; +// console.log(`buyers ATA is: ${buyerAta.toBase58()}`); + +// try{ +// ticketsBalanceBefore = (await connection.getTokenAccountBalance(buyerAta)).value.uiAmount ?? 0; +// console.log(`buyer has ${ticketsBalanceBefore} tickets already`); +// }catch{ +// const buyerAta = await getAssociatedTokenAddress(TICKETS_MINT, keypair.publicKey, false, TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID); + +// console.log("Buyer doesn't even has an ATA for this token, creating one"); +// const createAtaInstruction = createAssociatedTokenAccountInstruction( +// keypair.publicKey, // Payer +// buyerAta, // Associated Token Account to create +// keypair.publicKey, // Owner of the account +// TICKETS_MINT, // Token mint address +// TOKEN_PROGRAM_ID, // Token program ID +// ASSOCIATED_TOKEN_PROGRAM_ID // Associated token program ID +// ); + +// const transaction = new Transaction().add(createAtaInstruction); +// await provider.sendAndConfirm(transaction, [keypair]); +// console.log(`Created ATA: ${buyerAta.toBase58()}`); + +// console.log(`Buyer ATA Created: ${buyerAta}`); + +// } +// const [sellers_reg_pda] = await PublicKey.findProgramAddress([Buffer.from("sales_reg")], program.programId); +// console.log(`Sellers Reg PDA: ${sellers_reg_pda}`); + +// const seller = new PublicKey('cocD4r4yNpHxPq7CzUebxEMyLki3X4d2Y3HcTX5ptUc'); +// // Make the transaction to purchase tickets +// try{ +// console.log(`Purchasing ${amount} tickets from ${seller.toBase58()}`); +// const tx = await program.methods.purchaseTickets(new BN(1)).accounts({ +// seller:seller, +// mint: TICKETS_MINT, +// tokenProgram: TOKEN_PROGRAM_ID, +// }).rpc(); + +// console.log(`Ticket purchase transaction successful: ${tx}`); + +// return tx; +// }catch(e){ +// console.log("Failed to purchase tickets") +// console.log(e); +// return null; +// } +// } \ No newline at end of file diff --git a/src/sol/reader.js b/src/sol/reader.js new file mode 100644 index 0000000..65eb825 --- /dev/null +++ b/src/sol/reader.js @@ -0,0 +1,104 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetSolBalance = GetSolBalance; +exports.GetTokenAccount = GetTokenAccount; +exports.GetTokenBalanceByOwner = GetTokenBalanceByOwner; +exports.GetTokenBalanceByTA = GetTokenBalanceByTA; +exports.GetTicketsAccount = GetTicketsAccount; +exports.GetTicketsBalanceByOwner = GetTicketsBalanceByOwner; +exports.GetTicketsBalanceByTA = GetTicketsBalanceByTA; +const web3_js_1 = require("@solana/web3.js"); +const shared_1 = require("./shared"); +function GetSolBalance(wallet) { + return __awaiter(this, void 0, void 0, function* () { + const balance = yield shared_1.connection.getBalance(new web3_js_1.PublicKey(wallet)); + return balance; + }); +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +function GetTokenAccount(ownerAddress) { + return __awaiter(this, void 0, void 0, function* () { + const accountPublicKey = new web3_js_1.PublicKey(ownerAddress); + const account = yield shared_1.connection.getTokenAccountsByOwner(accountPublicKey, { mint: shared_1.TOKENS_MINT }); + try { + const tokenAddress = account.value[0].pubkey.toString(); + return tokenAddress; + } + catch (_a) { + return null; + } + }); +} +function GetTokenBalanceByOwner(owner) { + return __awaiter(this, void 0, void 0, function* () { + const tokenAccount = yield GetTokenAccount(owner); + if (tokenAccount == null) { + return 0; + } + console.log(tokenAccount); + return yield GetTokenBalanceByTA(tokenAccount); + }); +} +function GetTokenBalanceByTA(tokenAccountAddress) { + return __awaiter(this, void 0, void 0, function* () { + if (tokenAccountAddress == null) { + return 0; + } + const tokenAccount = new web3_js_1.PublicKey(tokenAccountAddress); + const info = yield shared_1.connection.getTokenAccountBalance(tokenAccount); + if (info.value.uiAmount == null) { + return -1; + } + console.log('Token Balance (using connection-Web3.js): ', info.value.uiAmount); + return info.value.uiAmount; + }); +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +function GetTicketsAccount(ownerAddress) { + return __awaiter(this, void 0, void 0, function* () { + const accountPublicKey = new web3_js_1.PublicKey(ownerAddress); + const account = yield shared_1.connection.getTokenAccountsByOwner(accountPublicKey, { mint: shared_1.TICKETS_MINT }); + console.log(JSON.stringify(account)); + try { + const tokenAddress = account.value[0].pubkey.toString(); + return tokenAddress; + } + catch (_a) { + return null; + } + }); +} +function GetTicketsBalanceByOwner(owner) { + return __awaiter(this, void 0, void 0, function* () { + const tokenAccount = yield GetTicketsAccount(owner); + if (tokenAccount == null) { + return 0; + } + console.log(tokenAccount); + return yield GetTicketsBalanceByTA(tokenAccount); + }); +} +function GetTicketsBalanceByTA(tokenAccountAddress) { + return __awaiter(this, void 0, void 0, function* () { + if (tokenAccountAddress == null) { + return 0; + } + const tokenAccount = new web3_js_1.PublicKey(tokenAccountAddress); + const info = yield shared_1.connection.getTokenAccountBalance(tokenAccount); + if (info.value.uiAmount == null) { + return -1; + } + console.log('Ticket Balance (using Solana-Web3.js): ', info.value.uiAmount); + return info.value.uiAmount; + }); +} +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/src/sol/reader.ts b/src/sol/reader.ts index fe060f6..8731d5d 100644 --- a/src/sol/reader.ts +++ b/src/sol/reader.ts @@ -3,7 +3,7 @@ import {connection, TICKETS_MINT, TOKENS_MINT} from './shared'; -export async function GetSolBalance(wallet){ +export async function GetSolBalance(wallet:string){ const balance = await connection.getBalance(new PublicKey(wallet)); return balance; @@ -11,7 +11,7 @@ export async function GetSolBalance(wallet){ //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -export async function GetTokenAccount(ownerAddress){ +export async function GetTokenAccount(ownerAddress:string){ const accountPublicKey = new PublicKey(ownerAddress); const account = await connection.getTokenAccountsByOwner(accountPublicKey, {mint: TOKENS_MINT}); try{ @@ -22,7 +22,7 @@ export async function GetTokenAccount(ownerAddress){ } } -export async function GetTokenBalanceByOwner(owner){ +export async function GetTokenBalanceByOwner(owner:string){ const tokenAccount = await GetTokenAccount(owner); if(tokenAccount==null){ return 0; @@ -31,7 +31,7 @@ export async function GetTokenBalanceByOwner(owner){ return await GetTokenBalanceByTA(tokenAccount); } -export async function GetTokenBalanceByTA(tokenAccountAddress){ +export async function GetTokenBalanceByTA(tokenAccountAddress:string){ if(tokenAccountAddress==null){ return 0; } @@ -47,10 +47,9 @@ export async function GetTokenBalanceByTA(tokenAccountAddress){ //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -export async function GetTicketsAccount(ownerAddress){ +export async function GetTicketsAccount(ownerAddress:string){ const accountPublicKey = new PublicKey(ownerAddress); const account = await connection.getTokenAccountsByOwner(accountPublicKey, {mint: TICKETS_MINT}); - try{ const tokenAddress = account.value[0].pubkey.toString(); return tokenAddress; @@ -59,7 +58,7 @@ export async function GetTicketsAccount(ownerAddress){ } } -export async function GetTicketsBalanceByOwner(owner){ +export async function GetTicketsBalanceByOwner(owner:string){ const tokenAccount = await GetTicketsAccount(owner); if(tokenAccount==null){ return 0; @@ -68,7 +67,7 @@ export async function GetTicketsBalanceByOwner(owner){ return await GetTicketsBalanceByTA(tokenAccount); } -export async function GetTicketsBalanceByTA(tokenAccountAddress){ +export async function GetTicketsBalanceByTA(tokenAccountAddress:string){ if(tokenAccountAddress==null){ return 0; } @@ -79,4 +78,8 @@ export async function GetTicketsBalanceByTA(tokenAccountAddress){ } console.log('Ticket Balance (using Solana-Web3.js): ', info.value.uiAmount); return info.value.uiAmount; -} \ No newline at end of file +} + +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + diff --git a/src/sol/shared.js b/src/sol/shared.js new file mode 100644 index 0000000..ee6ff0f --- /dev/null +++ b/src/sol/shared.js @@ -0,0 +1,23 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TOURNAMENT_SEED = exports.TOURNAMENT_VAULT_SEED = exports.PROGRAM = exports.PROVIDER = exports.OPERATOR_KEYPAIR = exports.OPERATOR_SK = exports.ASSOCIATED_TOKEN_PROGRAM_ID = exports.TOKEN_PROGRAM_ID = exports.connection = exports.TICKETS_MINT = exports.TOKENS_MINT = exports.TICKET_PRICE = exports.IDL = void 0; +const anchor_1 = require("@coral-xyz/anchor"); +exports.IDL = require('./IDL/tournaments.json'); +const web3_js_1 = require("@solana/web3.js"); +exports.TICKET_PRICE = 0.1; +exports.TOKENS_MINT = new web3_js_1.PublicKey('vcHyeKhk67CVumjzYV3m8cf6V8xcE85N9ay48pcyUpB'); +exports.TICKETS_MINT = new web3_js_1.PublicKey('tktUDLZhFGb9VW9zDxZ7HYDFuBooEf8daZEvPbBY7at'); +exports.connection = new web3_js_1.Connection((0, web3_js_1.clusterApiUrl)("devnet")); +exports.TOKEN_PROGRAM_ID = new web3_js_1.PublicKey('TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'); +exports.ASSOCIATED_TOKEN_PROGRAM_ID = new web3_js_1.PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL'); +const dotenv_1 = __importDefault(require("dotenv")); +dotenv_1.default.config(); +exports.OPERATOR_SK = JSON.parse(process.env.OPERATOR_SK); +exports.OPERATOR_KEYPAIR = web3_js_1.Keypair.fromSecretKey(Uint8Array.from(exports.OPERATOR_SK)); +exports.PROVIDER = new anchor_1.AnchorProvider(exports.connection, new anchor_1.Wallet(exports.OPERATOR_KEYPAIR)); +exports.PROGRAM = new anchor_1.Program(exports.IDL, exports.PROVIDER); +exports.TOURNAMENT_VAULT_SEED = Buffer.from("tournament_vault"); +exports.TOURNAMENT_SEED = Buffer.from("tournament"); diff --git a/src/sol/shared.ts b/src/sol/shared.ts index 47b7c49..1703d79 100644 --- a/src/sol/shared.ts +++ b/src/sol/shared.ts @@ -1,6 +1,23 @@ -import { Connection, PublicKey } from "@solana/web3.js"; +import { Tournaments } from "./IDL/tournaments"; +import {AnchorProvider, BN, Program, Wallet} from '@coral-xyz/anchor'; +import bs58 from "bs58"; +export const IDL = require('./IDL/tournaments.json'); +import { Connection, Keypair, PublicKey, clusterApiUrl } from "@solana/web3.js"; + +export const TICKET_PRICE = 0.1; export const TOKENS_MINT = new PublicKey('vcHyeKhk67CVumjzYV3m8cf6V8xcE85N9ay48pcyUpB'); export const TICKETS_MINT = new PublicKey('tktUDLZhFGb9VW9zDxZ7HYDFuBooEf8daZEvPbBY7at'); +export const connection = new Connection(clusterApiUrl("devnet")); +export const TOKEN_PROGRAM_ID = new PublicKey('TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'); +export const ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL'); -export const connection = new Connection("https://api.devnet.solana.com") \ No newline at end of file +import dotenv from 'dotenv'; +dotenv.config(); +export const OPERATOR_SK:number[] = JSON.parse(process.env.OPERATOR_SK!); +export const OPERATOR_KEYPAIR = Keypair.fromSecretKey(Uint8Array.from(OPERATOR_SK)); +export const PROVIDER = new AnchorProvider(connection, new Wallet(OPERATOR_KEYPAIR)); +export const PROGRAM = new Program(IDL, PROVIDER); + +export const TOURNAMENT_VAULT_SEED = Buffer.from("tournament_vault"); +export const TOURNAMENT_SEED = Buffer.from("tournament"); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index bd2ebf9..56a8ab8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,110 @@ { - "compilerOptions": { - "module": "commonjs", - "esModuleInterop": true, - "target": "es6", - "moduleResolution": "node", - "sourceMap": true, - "outDir": "dist" - }, - "lib": ["es2015"] - } \ No newline at end of file + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "noUncheckedSideEffectImports": true, /* Check side effect imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +}