self applause added as page with batteries included
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
b5ab8a6b81
commit
7bb4a473ba
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ghost-lite",
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.8",
|
||||
"description": "Web application for Ghost and Casper chain.",
|
||||
"author": "Uncle f4ts0 <f4ts0@ghostchain.io>",
|
||||
"maintainers": [
|
||||
@ -28,6 +28,7 @@
|
||||
"@polkadot-api/utils": "~0.1.2",
|
||||
"@polkadot-api/view-builder": "~0.4.3",
|
||||
"@polkadot-labs/hdkd-helpers": "^0.0.11",
|
||||
"@polkadot/util-crypto": "13.5.5",
|
||||
"@radix-ui/react-accordion": "^1.2.3",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-select": "^2.1.6",
|
||||
@ -47,9 +48,11 @@
|
||||
"react-icons": "^5.5.0",
|
||||
"react-router-dom": "^7.7.0",
|
||||
"rxjs": "^7.8.1",
|
||||
"scale-ts": "1.6.1",
|
||||
"swr": "^2.2.5",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"typescript": "^5.6.2"
|
||||
"typescript": "^5.6.2",
|
||||
"viem": "2.31.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.1.11",
|
||||
|
||||
377
pnpm-lock.yaml
377
pnpm-lock.yaml
@ -32,6 +32,9 @@ importers:
|
||||
'@polkadot-labs/hdkd-helpers':
|
||||
specifier: ^0.0.11
|
||||
version: 0.0.11
|
||||
'@polkadot/util-crypto':
|
||||
specifier: 13.5.5
|
||||
version: 13.5.5(@polkadot/util@13.5.8)
|
||||
'@radix-ui/react-accordion':
|
||||
specifier: ^1.2.3
|
||||
version: 1.2.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@ -89,6 +92,9 @@ importers:
|
||||
rxjs:
|
||||
specifier: ^7.8.1
|
||||
version: 7.8.2
|
||||
scale-ts:
|
||||
specifier: 1.6.1
|
||||
version: 1.6.1
|
||||
swr:
|
||||
specifier: ^2.2.5
|
||||
version: 2.3.4(react@18.3.1)
|
||||
@ -98,6 +104,9 @@ importers:
|
||||
typescript:
|
||||
specifier: ^5.6.2
|
||||
version: 5.6.2
|
||||
viem:
|
||||
specifier: 2.31.0
|
||||
version: 2.31.0(typescript@5.6.2)
|
||||
devDependencies:
|
||||
'@tailwindcss/postcss':
|
||||
specifier: ^4.1.11
|
||||
@ -150,6 +159,9 @@ importers:
|
||||
|
||||
packages:
|
||||
|
||||
'@adraffy/ens-normalize@1.11.1':
|
||||
resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==}
|
||||
|
||||
'@alloc/quick-lru@5.2.0':
|
||||
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
||||
engines: {node: '>=10'}
|
||||
@ -1179,10 +1191,18 @@ packages:
|
||||
'@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1':
|
||||
resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==}
|
||||
|
||||
'@noble/ciphers@1.3.0':
|
||||
resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@noble/curves@1.8.2':
|
||||
resolution: {integrity: sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@noble/curves@1.9.1':
|
||||
resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@noble/curves@1.9.2':
|
||||
resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
@ -1343,6 +1363,102 @@ packages:
|
||||
'@polkadot-labs/hdkd-helpers@0.0.11':
|
||||
resolution: {integrity: sha512-qPlWqC3NNV/2NYc5GEy+Ovi4UBAgkMGvMfyiYuj2BQN4lW59Q1T9coNx0Yp6XzsnJ1ddaF9PWaUtxj3LdM0IDw==}
|
||||
|
||||
'@polkadot/networks@13.5.5':
|
||||
resolution: {integrity: sha512-gTaKVSDRxjNAQ/oFMA83DXOo8A+/LP4XePbEHxNCku/Ox5R3IYGKTeZhlHgYtUZvdZgK+miyroEyz1Eq6Z9p+Q==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@polkadot/util-crypto@13.5.5':
|
||||
resolution: {integrity: sha512-LAHarViiPwjrXl05fXOV5pW6jvK8A0Y6uIJnttSSERjTKqG5O4VtgRAcqLXShTp1rEVE5T4DaIX5xZd7azBHyg==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@polkadot/util': 13.5.5
|
||||
|
||||
'@polkadot/util@13.5.5':
|
||||
resolution: {integrity: sha512-O3sGI8vWmv5o1cd8fDkc+cZGpUsG+ZUFAOitgv6bRt5llaBqS5VpTrUANEjfgUMgUuTn7Y2cPKGDLItYr5WnUg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@polkadot/util@13.5.8':
|
||||
resolution: {integrity: sha512-5xEfNoum/Ct+gYWN3AYvBQ8vq8KiS4HsY3BexPUPXvSXSx3Id/JYA5oFLYnkuRp8hwoQGjX0wqUJ6Hp8D8LHKw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@polkadot/wasm-bridge@7.5.1':
|
||||
resolution: {integrity: sha512-E+N3CSnX3YaXpAmfIQ+4bTyiAqJQKvVcMaXjkuL8Tp2zYffClWLG5e+RY15Uh+EWfUl9If4y6cLZi3D5NcpAGQ==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@polkadot/util': '*'
|
||||
'@polkadot/x-randomvalues': '*'
|
||||
|
||||
'@polkadot/wasm-crypto-asmjs@7.5.1':
|
||||
resolution: {integrity: sha512-jAg7Uusk+xeHQ+QHEH4c/N3b1kEGBqZb51cWe+yM61kKpQwVGZhNdlWetW6U23t/BMyZArIWMsZqmK/Ij0PHog==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@polkadot/util': '*'
|
||||
|
||||
'@polkadot/wasm-crypto-init@7.5.1':
|
||||
resolution: {integrity: sha512-Obu4ZEo5jYO6sN31eqCNOXo88rPVkP9TrUOyynuFCnXnXr8V/HlmY/YkAd9F87chZnkTJRlzak17kIWr+i7w3A==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@polkadot/util': '*'
|
||||
'@polkadot/x-randomvalues': '*'
|
||||
|
||||
'@polkadot/wasm-crypto-wasm@7.5.1':
|
||||
resolution: {integrity: sha512-S2yQSGbOGTcaV6UdipFVyEGanJvG6uD6Tg7XubxpiGbNAblsyYKeFcxyH1qCosk/4qf+GIUwlOL4ydhosZflqg==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@polkadot/util': '*'
|
||||
|
||||
'@polkadot/wasm-crypto@7.5.1':
|
||||
resolution: {integrity: sha512-acjt4VJ3w19v7b/SIPsV/5k9s6JsragHKPnwoZ0KTfBvAFXwzz80jUzVGxA06SKHacfCUe7vBRlz7M5oRby1Pw==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@polkadot/util': '*'
|
||||
'@polkadot/x-randomvalues': '*'
|
||||
|
||||
'@polkadot/wasm-util@7.5.1':
|
||||
resolution: {integrity: sha512-sbvu71isFhPXpvMVX+EkRnUg/+54Tx7Sf9BEMqxxoPj7cG1I/MKeDEwbQz6MaU4gm7xJqvEWCAemLFcXfHQ/2A==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@polkadot/util': '*'
|
||||
|
||||
'@polkadot/x-bigint@13.5.5':
|
||||
resolution: {integrity: sha512-SAd7Lfdgp6mz+utkoML8MN9FqTMCuPfk7v5rLJnm9vHgXw5uYnycbjH5Uc7ZgQIQWtMXJV3thrlltMan5DUXtA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@polkadot/x-bigint@13.5.8':
|
||||
resolution: {integrity: sha512-4ltTNgFDZoPnuQBrP7Z3m3imQ3xKb7jKScAT/Gy89h9siLYyJdZ+qawZfO1cll6fqYlka+k7USqGeyOEqoyCfg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@polkadot/x-global@13.5.5':
|
||||
resolution: {integrity: sha512-fw+VM191bodacSeieMm8Vmrym4jjevX08IINDcQTd1gIOjtE5CriJhwfBbAF4WnlTp/11jhhbX4/SvWMubXAzQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@polkadot/x-global@13.5.8':
|
||||
resolution: {integrity: sha512-KDK3CEG/RvfCu3w4HZ/iv6c49XrN5Hz/3mXUQdLfR+TFKADdNCoIhMZ9f7vHYgdnB9tlY9s6Dn2svY99h1wRiw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@polkadot/x-randomvalues@13.5.5':
|
||||
resolution: {integrity: sha512-W0AoNgr/NEVsHWegJUjUyI9Q1IoTHILIb/bkjyTcXTU3+2YFxP12ophhsI1dMaNbXqFotNyts7mNOsTVDnQNXA==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@polkadot/util': 13.5.5
|
||||
'@polkadot/wasm-util': '*'
|
||||
|
||||
'@polkadot/x-textdecoder@13.5.5':
|
||||
resolution: {integrity: sha512-KkZ1rqdJZ8tsRY0D5pLqfU8B/BrSQVEPMKHj4s/oc8dTrikfEUC+ELaH2jdrUqsZX6K/OTHjaF0J31YZcr7rCg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@polkadot/x-textdecoder@13.5.8':
|
||||
resolution: {integrity: sha512-Uzz6spRDzzQDQBN6PNpjz0HVp2kqhQVJRh1ShLP9rBg+nH4we9VGriWGG5stkgNKjRGT0Z7cvx0FupRQoNDU4A==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@polkadot/x-textencoder@13.5.5':
|
||||
resolution: {integrity: sha512-yEgUUojBb4goYf4V5I7urdJ+W+1aI13U1kZmUwMc+/G2YQz8pX3s/Tyb/iuxU5MlFh0AZZXP5NqUnFol+vwNEg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@polkadot/x-textencoder@13.5.8':
|
||||
resolution: {integrity: sha512-2jcVte6mUy+GXjpZsS7dFca8C2r8EGgaG5o7mVQZ+PjauD06O/UP2g48UuDJHGe1QCJN0f0WaoD+RNw9tOF2yQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@radix-ui/number@1.1.1':
|
||||
resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==}
|
||||
|
||||
@ -1780,6 +1896,12 @@ packages:
|
||||
'@scure/base@1.2.6':
|
||||
resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==}
|
||||
|
||||
'@scure/bip32@1.7.0':
|
||||
resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==}
|
||||
|
||||
'@scure/bip39@1.6.0':
|
||||
resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==}
|
||||
|
||||
'@sec-ant/readable-stream@0.4.1':
|
||||
resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
|
||||
|
||||
@ -1804,6 +1926,9 @@ packages:
|
||||
peerDependencies:
|
||||
smoldot: ^2
|
||||
|
||||
'@substrate/ss58-registry@1.51.0':
|
||||
resolution: {integrity: sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==}
|
||||
|
||||
'@swc/core-darwin-arm64@1.12.11':
|
||||
resolution: {integrity: sha512-J19Jj9Y5x/N0loExH7W0OI9OwwoVyxutDdkyq1o/kgXyBqmmzV7Y/Q9QekI2Fm/qc5mNeAdP7aj4boY4AY/JPw==}
|
||||
engines: {node: '>=10'}
|
||||
@ -1970,6 +2095,9 @@ packages:
|
||||
'@total-typescript/tsconfig@1.0.4':
|
||||
resolution: {integrity: sha512-fO4ctMPGz1kOFOQ4RCPBRBfMy3gDn+pegUfrGyUFRMv/Rd0ZM3/SHH3hFCYG4u6bPLG8OlmOGcBLDexvyr3A5w==}
|
||||
|
||||
'@types/bn.js@5.2.0':
|
||||
resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==}
|
||||
|
||||
'@types/estree@1.0.8':
|
||||
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||
|
||||
@ -2162,6 +2290,17 @@ packages:
|
||||
'@zag-js/utils@0.48.0':
|
||||
resolution: {integrity: sha512-VxNfAY3qMBm+VEsbM9+GmXTV9Ks2MxrLcXIcTK4qaGBl0y+DZZHN+b8DVMTLZpmkQK6wkJnkEnFC1Sv9dsQYkA==}
|
||||
|
||||
abitype@1.0.8:
|
||||
resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==}
|
||||
peerDependencies:
|
||||
typescript: '>=5.0.4'
|
||||
zod: ^3 >=3.22.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
acorn-jsx@5.3.2:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
@ -2295,6 +2434,9 @@ packages:
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
bn.js@5.2.2:
|
||||
resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==}
|
||||
|
||||
brace-expansion@1.1.12:
|
||||
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
|
||||
|
||||
@ -2710,6 +2852,9 @@ packages:
|
||||
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
eventemitter3@5.0.1:
|
||||
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
|
||||
|
||||
execa@9.6.0:
|
||||
resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==}
|
||||
engines: {node: ^18.19.0 || >=20.5.0}
|
||||
@ -3064,6 +3209,11 @@ packages:
|
||||
isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
isows@1.0.7:
|
||||
resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==}
|
||||
peerDependencies:
|
||||
ws: '*'
|
||||
|
||||
iterator.prototype@1.1.5:
|
||||
resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -3380,6 +3530,14 @@ packages:
|
||||
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
ox@0.7.1:
|
||||
resolution: {integrity: sha512-+k9fY9PRNuAMHRFIUbiK9Nt5seYHHzSQs9Bj+iMETcGtlpS7SmBzcGSVUQO3+nqGLEiNK4598pHNFlVRaZbRsg==}
|
||||
peerDependencies:
|
||||
typescript: '>=5.4.0'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
p-limit@3.1.0:
|
||||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||
engines: {node: '>=10'}
|
||||
@ -4056,6 +4214,14 @@ packages:
|
||||
validate-npm-package-license@3.0.4:
|
||||
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
|
||||
|
||||
viem@2.31.0:
|
||||
resolution: {integrity: sha512-U7OMQ6yqK+bRbEIarf2vqxL7unSEQvNxvML/1zG7suAmKuJmipqdVTVJGKBCJiYsm/EremyO2FS4dHIPpGv+eA==}
|
||||
peerDependencies:
|
||||
typescript: '>=5.0.4'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
vite-tsconfig-paths@5.1.4:
|
||||
resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==}
|
||||
peerDependencies:
|
||||
@ -4149,6 +4315,18 @@ packages:
|
||||
resolution: {integrity: sha512-DqUx8GI3r9BFWwU2DPKddL1E7xWfbFED82mLVhGXKlFEPe8IkBftzO7WfNwHtk7oGDHDeuH/o8VMpzzfMwmLUA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
ws@8.18.2:
|
||||
resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: '>=5.0.2'
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
ws@8.18.3:
|
||||
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
@ -4182,6 +4360,8 @@ packages:
|
||||
|
||||
snapshots:
|
||||
|
||||
'@adraffy/ens-normalize@1.11.1': {}
|
||||
|
||||
'@alloc/quick-lru@5.2.0': {}
|
||||
|
||||
'@ampproject/remapping@2.3.0':
|
||||
@ -5267,10 +5447,16 @@ snapshots:
|
||||
dependencies:
|
||||
eslint-scope: 5.1.1
|
||||
|
||||
'@noble/ciphers@1.3.0': {}
|
||||
|
||||
'@noble/curves@1.8.2':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.7.2
|
||||
|
||||
'@noble/curves@1.9.1':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.8.0
|
||||
|
||||
'@noble/curves@1.9.2':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.8.0
|
||||
@ -5556,6 +5742,134 @@ snapshots:
|
||||
micro-sr25519: 0.1.3
|
||||
scale-ts: 1.6.1
|
||||
|
||||
'@polkadot/networks@13.5.5':
|
||||
dependencies:
|
||||
'@polkadot/util': 13.5.5
|
||||
'@substrate/ss58-registry': 1.51.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/util-crypto@13.5.5(@polkadot/util@13.5.8)':
|
||||
dependencies:
|
||||
'@noble/curves': 1.9.2
|
||||
'@noble/hashes': 1.8.0
|
||||
'@polkadot/networks': 13.5.5
|
||||
'@polkadot/util': 13.5.8
|
||||
'@polkadot/wasm-crypto': 7.5.1(@polkadot/util@13.5.8)(@polkadot/x-randomvalues@13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8)))
|
||||
'@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.8)
|
||||
'@polkadot/x-bigint': 13.5.5
|
||||
'@polkadot/x-randomvalues': 13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8))
|
||||
'@scure/base': 1.2.6
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/util@13.5.5':
|
||||
dependencies:
|
||||
'@polkadot/x-bigint': 13.5.5
|
||||
'@polkadot/x-global': 13.5.5
|
||||
'@polkadot/x-textdecoder': 13.5.5
|
||||
'@polkadot/x-textencoder': 13.5.5
|
||||
'@types/bn.js': 5.2.0
|
||||
bn.js: 5.2.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/util@13.5.8':
|
||||
dependencies:
|
||||
'@polkadot/x-bigint': 13.5.8
|
||||
'@polkadot/x-global': 13.5.8
|
||||
'@polkadot/x-textdecoder': 13.5.8
|
||||
'@polkadot/x-textencoder': 13.5.8
|
||||
'@types/bn.js': 5.2.0
|
||||
bn.js: 5.2.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/wasm-bridge@7.5.1(@polkadot/util@13.5.8)(@polkadot/x-randomvalues@13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8)))':
|
||||
dependencies:
|
||||
'@polkadot/util': 13.5.8
|
||||
'@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.8)
|
||||
'@polkadot/x-randomvalues': 13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8))
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/wasm-crypto-asmjs@7.5.1(@polkadot/util@13.5.8)':
|
||||
dependencies:
|
||||
'@polkadot/util': 13.5.8
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/wasm-crypto-init@7.5.1(@polkadot/util@13.5.8)(@polkadot/x-randomvalues@13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8)))':
|
||||
dependencies:
|
||||
'@polkadot/util': 13.5.8
|
||||
'@polkadot/wasm-bridge': 7.5.1(@polkadot/util@13.5.8)(@polkadot/x-randomvalues@13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8)))
|
||||
'@polkadot/wasm-crypto-asmjs': 7.5.1(@polkadot/util@13.5.8)
|
||||
'@polkadot/wasm-crypto-wasm': 7.5.1(@polkadot/util@13.5.8)
|
||||
'@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.8)
|
||||
'@polkadot/x-randomvalues': 13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8))
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/wasm-crypto-wasm@7.5.1(@polkadot/util@13.5.8)':
|
||||
dependencies:
|
||||
'@polkadot/util': 13.5.8
|
||||
'@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.8)
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/wasm-crypto@7.5.1(@polkadot/util@13.5.8)(@polkadot/x-randomvalues@13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8)))':
|
||||
dependencies:
|
||||
'@polkadot/util': 13.5.8
|
||||
'@polkadot/wasm-bridge': 7.5.1(@polkadot/util@13.5.8)(@polkadot/x-randomvalues@13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8)))
|
||||
'@polkadot/wasm-crypto-asmjs': 7.5.1(@polkadot/util@13.5.8)
|
||||
'@polkadot/wasm-crypto-init': 7.5.1(@polkadot/util@13.5.8)(@polkadot/x-randomvalues@13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8)))
|
||||
'@polkadot/wasm-crypto-wasm': 7.5.1(@polkadot/util@13.5.8)
|
||||
'@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.8)
|
||||
'@polkadot/x-randomvalues': 13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8))
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8)':
|
||||
dependencies:
|
||||
'@polkadot/util': 13.5.8
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/x-bigint@13.5.5':
|
||||
dependencies:
|
||||
'@polkadot/x-global': 13.5.5
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/x-bigint@13.5.8':
|
||||
dependencies:
|
||||
'@polkadot/x-global': 13.5.8
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/x-global@13.5.5':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/x-global@13.5.8':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/x-randomvalues@13.5.5(@polkadot/util@13.5.8)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.8))':
|
||||
dependencies:
|
||||
'@polkadot/util': 13.5.8
|
||||
'@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.8)
|
||||
'@polkadot/x-global': 13.5.5
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/x-textdecoder@13.5.5':
|
||||
dependencies:
|
||||
'@polkadot/x-global': 13.5.5
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/x-textdecoder@13.5.8':
|
||||
dependencies:
|
||||
'@polkadot/x-global': 13.5.8
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/x-textencoder@13.5.5':
|
||||
dependencies:
|
||||
'@polkadot/x-global': 13.5.5
|
||||
tslib: 2.8.1
|
||||
|
||||
'@polkadot/x-textencoder@13.5.8':
|
||||
dependencies:
|
||||
'@polkadot/x-global': 13.5.8
|
||||
tslib: 2.8.1
|
||||
|
||||
'@radix-ui/number@1.1.1': {}
|
||||
|
||||
'@radix-ui/primitive@1.1.2': {}
|
||||
@ -5917,6 +6231,17 @@ snapshots:
|
||||
|
||||
'@scure/base@1.2.6': {}
|
||||
|
||||
'@scure/bip32@1.7.0':
|
||||
dependencies:
|
||||
'@noble/curves': 1.9.2
|
||||
'@noble/hashes': 1.8.0
|
||||
'@scure/base': 1.2.6
|
||||
|
||||
'@scure/bip39@1.6.0':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.8.0
|
||||
'@scure/base': 1.2.6
|
||||
|
||||
'@sec-ant/readable-stream@0.4.1': {}
|
||||
|
||||
'@sindresorhus/merge-streams@4.0.0': {}
|
||||
@ -5949,6 +6274,8 @@ snapshots:
|
||||
rxjs: 7.8.2
|
||||
smoldot: 2.0.36
|
||||
|
||||
'@substrate/ss58-registry@1.51.0': {}
|
||||
|
||||
'@swc/core-darwin-arm64@1.12.11':
|
||||
optional: true
|
||||
|
||||
@ -6075,6 +6402,10 @@ snapshots:
|
||||
|
||||
'@total-typescript/tsconfig@1.0.4': {}
|
||||
|
||||
'@types/bn.js@5.2.0':
|
||||
dependencies:
|
||||
'@types/node': 24.0.15
|
||||
|
||||
'@types/estree@1.0.8': {}
|
||||
|
||||
'@types/json-schema@7.0.15': {}
|
||||
@ -6337,6 +6668,10 @@ snapshots:
|
||||
|
||||
'@zag-js/utils@0.48.0': {}
|
||||
|
||||
abitype@1.0.8(typescript@5.6.2):
|
||||
optionalDependencies:
|
||||
typescript: 5.6.2
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.15.0):
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
@ -6517,6 +6852,8 @@ snapshots:
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
bn.js@5.2.2: {}
|
||||
|
||||
brace-expansion@1.1.12:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
@ -7146,6 +7483,8 @@ snapshots:
|
||||
|
||||
esutils@2.0.3: {}
|
||||
|
||||
eventemitter3@5.0.1: {}
|
||||
|
||||
execa@9.6.0:
|
||||
dependencies:
|
||||
'@sindresorhus/merge-streams': 4.0.0
|
||||
@ -7511,6 +7850,10 @@ snapshots:
|
||||
|
||||
isexe@2.0.0: {}
|
||||
|
||||
isows@1.0.7(ws@8.18.2):
|
||||
dependencies:
|
||||
ws: 8.18.2
|
||||
|
||||
iterator.prototype@1.1.5:
|
||||
dependencies:
|
||||
define-data-property: 1.1.4
|
||||
@ -7811,6 +8154,21 @@ snapshots:
|
||||
object-keys: 1.1.1
|
||||
safe-push-apply: 1.0.0
|
||||
|
||||
ox@0.7.1(typescript@5.6.2):
|
||||
dependencies:
|
||||
'@adraffy/ens-normalize': 1.11.1
|
||||
'@noble/ciphers': 1.3.0
|
||||
'@noble/curves': 1.9.2
|
||||
'@noble/hashes': 1.8.0
|
||||
'@scure/bip32': 1.7.0
|
||||
'@scure/bip39': 1.6.0
|
||||
abitype: 1.0.8(typescript@5.6.2)
|
||||
eventemitter3: 5.0.1
|
||||
optionalDependencies:
|
||||
typescript: 5.6.2
|
||||
transitivePeerDependencies:
|
||||
- zod
|
||||
|
||||
p-limit@3.1.0:
|
||||
dependencies:
|
||||
yocto-queue: 0.1.0
|
||||
@ -8559,6 +8917,23 @@ snapshots:
|
||||
spdx-correct: 3.2.0
|
||||
spdx-expression-parse: 3.0.1
|
||||
|
||||
viem@2.31.0(typescript@5.6.2):
|
||||
dependencies:
|
||||
'@noble/curves': 1.9.1
|
||||
'@noble/hashes': 1.8.0
|
||||
'@scure/bip32': 1.7.0
|
||||
'@scure/bip39': 1.6.0
|
||||
abitype: 1.0.8(typescript@5.6.2)
|
||||
isows: 1.0.7(ws@8.18.2)
|
||||
ox: 0.7.1(typescript@5.6.2)
|
||||
ws: 8.18.2
|
||||
optionalDependencies:
|
||||
typescript: 5.6.2
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
- zod
|
||||
|
||||
vite-tsconfig-paths@5.1.4(typescript@5.6.2)(vite@5.4.19(@types/node@24.0.15)(lightningcss@1.30.1)):
|
||||
dependencies:
|
||||
debug: 4.4.1
|
||||
@ -8669,6 +9044,8 @@ snapshots:
|
||||
type-fest: 4.41.0
|
||||
write-json-file: 6.0.0
|
||||
|
||||
ws@8.18.2: {}
|
||||
|
||||
ws@8.18.3: {}
|
||||
|
||||
yallist@3.1.1: {}
|
||||
|
||||
@ -14,6 +14,8 @@ export const Header = () => {
|
||||
return "Address Book"
|
||||
case "nominations":
|
||||
return "Nominations"
|
||||
case "applause":
|
||||
return "Self Applause"
|
||||
default:
|
||||
return "Health Check";
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { HeartPulse, SendToBack, Book, Users } from "lucide-react"
|
||||
import { HeartPulse, SendToBack, Book, Users, Handshake } from "lucide-react"
|
||||
import { FaGithub } from "react-icons/fa"
|
||||
import { Link, useLocation } from "react-router-dom"
|
||||
import { useEffect } from "react"
|
||||
@ -124,6 +124,12 @@ export const Sidebar = () => {
|
||||
<span className={`md:block hidden ${cName("title", currentPath, "nominations")}`} >Nominations</span>
|
||||
</div>
|
||||
</Link>
|
||||
<Link to="/applause" className="relative">
|
||||
<div className={cName("item", currentPath, "applause")}>
|
||||
<Handshake className={cName("icon", currentPath, "applause")} />
|
||||
<span className={`md:block hidden ${cName("title", currentPath, "applause")}`} >Self Applause</span>
|
||||
</div>
|
||||
</Link>
|
||||
</ul>
|
||||
|
||||
<div className="w-full text-center flex-grow flex flex-col justify-end">
|
||||
|
||||
@ -13,6 +13,7 @@ const HealthCheck = lazy(() => import("./HealthCheck").then(module => ({ default
|
||||
const Transactions = lazy(() => import("./Transactions").then(module => ({ default: module.Transactions })))
|
||||
const Nominations = lazy(() => import("./Nominations").then(module => ({ default: module.Nominations })))
|
||||
const AddressBook = lazy(() => import("./AddressBook").then(module => ({ default: module.AddressBook })))
|
||||
const SelfApplause = lazy(() => import("./SelfApplause").then(module => ({ default: module.SelfApplause })))
|
||||
|
||||
export const App = () => {
|
||||
return (
|
||||
@ -29,6 +30,7 @@ export const App = () => {
|
||||
<Route path="/health" element={<HealthCheck />} />
|
||||
<Route path="/transactions" element={<Transactions />} />
|
||||
<Route path="/book" element={<AddressBook />} />
|
||||
<Route path="/applause" element={<SelfApplause />} />
|
||||
<Route path="/nominations" element={<Nominations />} />
|
||||
<Route path="*" element={<Navigate to="/health" replace />} />
|
||||
</Routes>
|
||||
|
||||
287
src/containers/SelfApplause.tsx
Normal file
287
src/containers/SelfApplause.tsx
Normal file
@ -0,0 +1,287 @@
|
||||
import { useState, useEffect, useMemo } from "react"
|
||||
|
||||
import { useSearchParams } from "react-router-dom"
|
||||
import { Hand, BadgeAlert, BadgeCheck, ArrowBigRightDash } from "lucide-react"
|
||||
import { u64, u128 } from "scale-ts"
|
||||
import { keccak256 } from "viem"
|
||||
import { decodeAddress } from "@polkadot/util-crypto"
|
||||
|
||||
import { Row } from "./Row"
|
||||
import { Sender } from "./Accounts"
|
||||
import { Input } from "../components/ui/input"
|
||||
import { Button } from "../components/ui/button"
|
||||
|
||||
// http://localhost:5173/#/applause?networkId=11155111&sessionIndex=591&receiver=sfGvT6dSpR1Sodpu7XPy2oa4Pbu9UaKjJ6mnLP8JmdSktnde7&amount=0.010000000&transactionHash=0x29e80e04eef8db2eda43e36465fb3adda79b19eb22d695303686b64bd1055a21
|
||||
|
||||
import {
|
||||
useChainSpecV1,
|
||||
useSystemAccount,
|
||||
useUnstableProvider,
|
||||
useApplauseThreshold,
|
||||
useCurrentIndex,
|
||||
useAuthorities,
|
||||
useClapsInSession,
|
||||
useReceivedClaps,
|
||||
useApplausesForTransaction,
|
||||
useSelfApplauseCalldata,
|
||||
useTransactionStatusProvider,
|
||||
SessionAuthorityInfo
|
||||
} from "../hooks"
|
||||
|
||||
export const SelfApplause = () => {
|
||||
const [searchParams] = useSearchParams()
|
||||
|
||||
const [networkId, setNetworkId] = useState("")
|
||||
const [sessionIndex, setSessionIndex] = useState("")
|
||||
const [transactionHash, setTransactionHash] = useState("")
|
||||
const [receiver, setReceiver] = useState("")
|
||||
const [bridgedAmount, setBridgedAmount] = useState("")
|
||||
|
||||
const { account, accounts, connectAccount } = useUnstableProvider()
|
||||
const chainSpecV1 = useChainSpecV1()
|
||||
|
||||
const tokenDecimals: number = chainSpecV1?.properties?.tokenDecimals ?? 0
|
||||
const tokenSymbol: string = chainSpecV1?.properties?.tokenSymbol ?? ""
|
||||
const ss58Format: number = chainSpecV1?.properties?.ss58Format ?? 1995
|
||||
|
||||
const nextSessionIndex = useMemo(() => {
|
||||
const number = +sessionIndex
|
||||
return isNaN(number) ? undefined : number + 1
|
||||
}, [sessionIndex])
|
||||
|
||||
const amountConverted = useMemo(() => {
|
||||
const amountNum = parseFloat(bridgedAmount);
|
||||
if (isNaN(amountNum)) {
|
||||
return 0n;
|
||||
}
|
||||
return BigInt(Math.floor(amountNum * Math.pow(10, tokenDecimals)))
|
||||
}, [bridgedAmount, tokenDecimals])
|
||||
|
||||
const hashedArguments = useMemo(() => {
|
||||
try {
|
||||
const amountEncoded = u128.enc(amountConverted)
|
||||
const networkIdEncoded = u64.enc(BigInt(networkId))
|
||||
const addressEncoded = decodeAddress(receiver, false, ss58Format)
|
||||
|
||||
const clapArgsStr = new Uint8Array([
|
||||
...addressEncoded,
|
||||
...amountEncoded,
|
||||
...networkIdEncoded
|
||||
])
|
||||
return keccak256(clapArgsStr)
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
}, [receiver, amountConverted, ss58Format, networkId])
|
||||
|
||||
const {
|
||||
isSubmittingTransaction,
|
||||
handleTransaction,
|
||||
renderStatus,
|
||||
} = useTransactionStatusProvider()
|
||||
|
||||
const appluseThreshold = useApplauseThreshold()
|
||||
const currentSession = useCurrentIndex()
|
||||
|
||||
const authorities = useAuthorities({ currentSession: Number(sessionIndex) })
|
||||
const authoritiesNext = useAuthorities({ currentSession: nextSessionIndex })
|
||||
const clapsInSession = useClapsInSession({
|
||||
currentSession: Number(sessionIndex)
|
||||
})
|
||||
const clapsInNextSession = useClapsInSession({
|
||||
currentSession: nextSessionIndex
|
||||
})
|
||||
const receivedClaps = useReceivedClaps({
|
||||
currentSession: Number(sessionIndex),
|
||||
txHash: transactionHash,
|
||||
argsHash: hashedArguments
|
||||
})
|
||||
const receivedClapsNext = useReceivedClaps({
|
||||
currentSession: nextSessionIndex,
|
||||
txHash: transactionHash,
|
||||
argsHash: hashedArguments
|
||||
})
|
||||
const transactionApplaused = useApplausesForTransaction({
|
||||
currentSession: Number(sessionIndex),
|
||||
txHash: transactionHash,
|
||||
argsHash: hashedArguments
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
setNetworkId(searchParams.get("networkId") ?? "")
|
||||
setSessionIndex(searchParams.get("sessionIndex") ?? "")
|
||||
setTransactionHash(searchParams.get("transactionHash") ?? "")
|
||||
setReceiver(searchParams.get("receiver") ?? "")
|
||||
setBridgedAmount(searchParams.get("amount") ?? "")
|
||||
}, [searchParams])
|
||||
|
||||
const senderAccount = useSystemAccount({
|
||||
account: account
|
||||
? account.address
|
||||
: undefined
|
||||
})
|
||||
|
||||
const disabledInSession = useMemo(() => {
|
||||
return clapsInSession?.filter((info: SessionAuthorityInfo) => info.disabled) ?? []
|
||||
}, [clapsInSession])
|
||||
|
||||
const totalDisabled = useMemo(() => {
|
||||
let numberOfDisabled = clapsInSession?.filter((info: SessionAuthorityInfo) => info.disabled).length ?? 0
|
||||
clapsInNextSession?.forEach((info: SessionAuthorityInfo, index: number) => {
|
||||
if (info.disabled) {
|
||||
const authority = authoritiesNext?.at(index)
|
||||
if (authority) {
|
||||
const myIndex = authorities?.indexOf(authority)
|
||||
if (myIndex) {
|
||||
numberOfDisabled += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return numberOfDisabled
|
||||
}, [clapsInSession, clapsInNextSession, authoritiesNext, authorities])
|
||||
|
||||
const totalReceivedClaps = useMemo(() => {
|
||||
let totalClaps = receivedClaps?.length ?? 0
|
||||
for (const index of (receivedClapsNext ?? [])) {
|
||||
const authority = authoritiesNext[index];
|
||||
if (authority) {
|
||||
const myIndex = authorities?.indexOf(authority)
|
||||
if (myIndex) {
|
||||
totalClaps += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return totalClaps
|
||||
}, [authorities, receivedClaps, receivedClapsNext, authoritiesNext])
|
||||
|
||||
const applausePossible = useMemo(() => {
|
||||
const value = totalReceivedClaps * 100 / (authorities?.length ?? 0) - totalDisabled
|
||||
return value > appluseThreshold
|
||||
}, [authorities, totalReceivedClaps, totalDisabled, appluseThreshold])
|
||||
|
||||
const loadedCorrectly = useMemo(() => {
|
||||
return clapsInSession && authorities && disabledInSession
|
||||
}, [clapsInSession, authorities, disabledInSession])
|
||||
|
||||
const applyDecimals = (value = 0n, decimals = 0, tokenSymbol = "CSPR") => {
|
||||
if (!value) return `0 ${tokenSymbol}`
|
||||
const numberValue = Number(value) / Math.pow(10, decimals)
|
||||
const formatter = new Intl.NumberFormat("en-US", {
|
||||
minimumFractionDigits: 6,
|
||||
maximumFractionDigits: 6,
|
||||
})
|
||||
return `${formatter.format(numberValue)} ${tokenSymbol}`
|
||||
}
|
||||
|
||||
const calldata = useSelfApplauseCalldata(
|
||||
Number(networkId),
|
||||
Number(sessionIndex),
|
||||
transactionHash,
|
||||
receiver,
|
||||
amountConverted
|
||||
)
|
||||
const handleOnSelfApplause = () => handleTransaction({ calldata: calldata, txName: "self_applause" })
|
||||
|
||||
return (
|
||||
<div className="sm:w-[500px] w-[85%] h-fit flex flex-col flex-1 gap-2 justify-center self-center rounded py-2">
|
||||
<div className="bg-muted p-4 rounded flex flex-col gap-2">
|
||||
<Sender
|
||||
account={account?.address ?? ""}
|
||||
accounts={accounts?.map(acc => acc?.address ?? "") ?? []}
|
||||
senderAccount={senderAccount}
|
||||
senderBalance={applyDecimals(senderAccount?.data.free ?? 0n, tokenDecimals, tokenSymbol)}
|
||||
tokenDecimals={tokenDecimals}
|
||||
tokenSymbol={tokenSymbol}
|
||||
connectAccount={connectAccount}
|
||||
applyDecimals={applyDecimals}
|
||||
/>
|
||||
<Row title={"Network Id"} element={<Input
|
||||
onChange={(e) => setNetworkId(e.target.value)}
|
||||
value={networkId}
|
||||
aria-label="NetworkId"
|
||||
type="text"
|
||||
className="sm:w-[300px] w-full"
|
||||
placeholder={"0"}
|
||||
/>} />
|
||||
<Row title={"Session Index"} element={<Input
|
||||
onChange={(e) => setSessionIndex(e.target.value)}
|
||||
value={sessionIndex}
|
||||
aria-label="SessionIndex"
|
||||
type="text"
|
||||
className="sm:w-[300px] w-full"
|
||||
placeholder={"0"}
|
||||
/>} />
|
||||
<Row title={"Transaction Hash"} element={<Input
|
||||
onChange={(e) => setTransactionHash(e.target.value)}
|
||||
value={transactionHash}
|
||||
aria-label="TransactionHash"
|
||||
type="text"
|
||||
className="sm:w-[300px] w-full"
|
||||
placeholder={"0x..."}
|
||||
/>} />
|
||||
<Row title={"Receiver Address"} element={<Input
|
||||
onChange={(e) => setReceiver(e.target.value)}
|
||||
value={receiver}
|
||||
aria-label="ReceiverAddress"
|
||||
type="text"
|
||||
className="sm:w-[300px] w-full"
|
||||
placeholder={"sf..."}
|
||||
/>} />
|
||||
<Row title={"Bridged Amount"} element={<Input
|
||||
onChange={(e) => setBridgedAmount(e.target.value)}
|
||||
value={bridgedAmount}
|
||||
aria-label="BridgedAmount"
|
||||
type="text"
|
||||
className="sm:w-[300px] w-full"
|
||||
placeholder={"0"}
|
||||
/>} />
|
||||
{loadedCorrectly &&
|
||||
<div className="flex justify-around items-center mt-4 mb-2">
|
||||
<div className="flex flex-col justify-center items-center hover:text-secondary-foreground cursor-pointer">
|
||||
<div className="text-xs">
|
||||
Actual
|
||||
</div>
|
||||
<BadgeAlert className="w-8 h-8 inline-block" />
|
||||
<div className="text-xs">
|
||||
{clapsInSession.length} / {authorities.length - disabledInSession.length}
|
||||
</div>
|
||||
</div>
|
||||
<ArrowBigRightDash className="w-6 h-6 inline-block" />
|
||||
<div className="flex flex-col justify-center items-center hover:text-secondary-foreground cursor-pointer">
|
||||
<div className="text-xs">
|
||||
Possible
|
||||
</div>
|
||||
<BadgeCheck className="w-8 h-8 inline-block" />
|
||||
<div className="text-xs">
|
||||
{totalReceivedClaps} / {authorities ? authorities.length - totalDisabled : 0}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
className="text-sm p-4 w-full mt-4"
|
||||
onClick={handleOnSelfApplause}
|
||||
disabled={
|
||||
isSubmittingTransaction || transactionApplaused ||
|
||||
!loadedCorrectly || !account || !applausePossible ||
|
||||
currentSession < (nextSessionIndex ?? 0)
|
||||
}
|
||||
>
|
||||
<Hand className="w-4 h-4 inline-block mr-2" />
|
||||
{transactionApplaused
|
||||
? "Already applaused"
|
||||
: !applausePossible
|
||||
? "Impossible to applause"
|
||||
: currentSession < (nextSessionIndex ?? 0)
|
||||
? "Not ready yet"
|
||||
: "Try applause"
|
||||
}
|
||||
</Button>
|
||||
{renderStatus()}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -18,3 +18,8 @@ export * from "./useNominations"
|
||||
export * from "./useLedger"
|
||||
export * from "./usePayee"
|
||||
export * from "./useSlasingSpans"
|
||||
export * from "./useApplausesForTransaction"
|
||||
export * from "./useAuthorities"
|
||||
export * from "./useClapsInSession"
|
||||
export * from "./useReceivedClaps"
|
||||
export * from "./useCurrentIndex"
|
||||
|
||||
54
src/hooks/useApplausesForTransaction.tsx
Normal file
54
src/hooks/useApplausesForTransaction.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import useSWRSubscription from "swr/subscription"
|
||||
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders"
|
||||
import type { BlockInfo } from "@polkadot-api/observable-client"
|
||||
import { distinct, filter, map, mergeMap } from "rxjs"
|
||||
import { fromHex } from "@polkadot-api/utils";
|
||||
|
||||
import { useUnstableProvider } from "./useUnstableProvider"
|
||||
import { useMetadata } from "./useMetadata"
|
||||
|
||||
interface ApplausesForTransactionInterface {
|
||||
currentSession?: Number;
|
||||
txHash?: string;
|
||||
argsHash?: string;
|
||||
}
|
||||
|
||||
export const useApplausesForTransaction = ({ currentSession, txHash, argsHash }: ApplausesForTransactionInterface) => {
|
||||
const { chainHead$, chainId } = useUnstableProvider()
|
||||
const metadata = useMetadata()
|
||||
const { data: applausesForTransaction } = useSWRSubscription(
|
||||
chainHead$ && txHash && argsHash && currentSession && chainId && metadata
|
||||
? ["applausesForTransaction", chainHead$, txHash, argsHash, currentSession, chainId, metadata]
|
||||
: null,
|
||||
([_, chainHead$, txHash, argsHash, currentSession, chainId, metadata], { next }) => {
|
||||
const { finalized$, storage$ } = chainHead$
|
||||
const subscription = finalized$.pipe(
|
||||
filter(Boolean),
|
||||
mergeMap((blockInfo: BlockInfo) => {
|
||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||
const applausesForTransaction = builder.buildStorage("GhostSlowClaps", "ApplausesForTransaction")
|
||||
|
||||
return storage$(blockInfo?.hash, "value", () =>
|
||||
applausesForTransaction?.keys.enc(
|
||||
currentSession,
|
||||
{ asBytes: () => fromHex(txHash) },
|
||||
{ asBytes: () => fromHex(argsHash) },
|
||||
)
|
||||
).pipe(
|
||||
filter(Boolean),
|
||||
distinct(),
|
||||
map((value: string) => applausesForTransaction?.value.dec(value) as boolean)
|
||||
)
|
||||
}),
|
||||
)
|
||||
.subscribe({
|
||||
next(applausesForTransaction: boolean) {
|
||||
next(null, applausesForTransaction)
|
||||
},
|
||||
error: next,
|
||||
})
|
||||
return () => subscription.unsubscribe()
|
||||
}
|
||||
)
|
||||
return applausesForTransaction
|
||||
}
|
||||
46
src/hooks/useAuthorities.tsx
Normal file
46
src/hooks/useAuthorities.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
import useSWRSubscription from "swr/subscription"
|
||||
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders"
|
||||
import type { BlockInfo } from "@polkadot-api/observable-client"
|
||||
import { distinct, filter, map, mergeMap } from "rxjs"
|
||||
|
||||
import { useUnstableProvider } from "./useUnstableProvider"
|
||||
import { useMetadata } from "./useMetadata"
|
||||
|
||||
interface AuthoritiesInterface {
|
||||
currentSession?: Number;
|
||||
}
|
||||
|
||||
export const useAuthorities = ({ currentSession }: AuthoritiesInterface) => {
|
||||
const { chainHead$, chainId } = useUnstableProvider()
|
||||
const metadata = useMetadata()
|
||||
const { data: slowClapAuthorities } = useSWRSubscription(
|
||||
chainHead$ && chainId && metadata
|
||||
? ["slowClapAuthorities", chainHead$, currentSession, chainId, metadata]
|
||||
: null,
|
||||
([_, chainHead$, currentSession, chainId, metadata], { next }) => {
|
||||
const { finalized$, storage$ } = chainHead$
|
||||
const subscription = finalized$.pipe(
|
||||
filter(Boolean),
|
||||
mergeMap((blockInfo: BlockInfo) => {
|
||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||
const slowClapAuthorities = builder.buildStorage("GhostSlowClaps", "Authorities")
|
||||
return storage$(blockInfo?.hash, "value", () =>
|
||||
slowClapAuthorities?.keys.enc(currentSession)
|
||||
).pipe(
|
||||
filter(Boolean),
|
||||
distinct(),
|
||||
map((value: string) => slowClapAuthorities?.value.dec(value) as any)
|
||||
)
|
||||
}),
|
||||
)
|
||||
.subscribe({
|
||||
next(slowClapAuthorities: any) {
|
||||
next(null, slowClapAuthorities)
|
||||
},
|
||||
error: next,
|
||||
})
|
||||
return () => subscription.unsubscribe()
|
||||
}
|
||||
)
|
||||
return slowClapAuthorities?.map((authority: any) => authority?.asHex())
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
import useSWR from "swr"
|
||||
|
||||
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders"
|
||||
import { mergeUint8, toHex } from "@polkadot-api/utils"
|
||||
import { type SS58String, Enum } from "@polkadot-api/substrate-bindings"
|
||||
import { mergeUint8, toHex, fromHex } from "@polkadot-api/utils"
|
||||
import { type SS58String, Binary, Enum } from "@polkadot-api/substrate-bindings"
|
||||
|
||||
import { useUnstableProvider } from "./useUnstableProvider"
|
||||
import { useMetadata } from "./useMetadata"
|
||||
@ -56,7 +56,7 @@ export const useTransferCalldata = (destination: SS58String | undefined, amount:
|
||||
const metadata = useMetadata()
|
||||
const { data: calldata } = useSWR(
|
||||
client && chainId && destination && amount && metadata
|
||||
? ["metadata", client, chainId, metadata, destination, amount]
|
||||
? ["transfer_allow_death", client, chainId, metadata, destination, amount]
|
||||
: null,
|
||||
([_, client, _chainId, metadata, destination, amount]) => {
|
||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||
@ -227,3 +227,39 @@ export const usePayeeCalldata = (expectedPayee: string | undefined, destinationR
|
||||
)
|
||||
return calldata
|
||||
}
|
||||
|
||||
export const useSelfApplauseCalldata = (
|
||||
networkId?: Number,
|
||||
sessionIndex?: Number,
|
||||
transactionHash?: string,
|
||||
receiver?: string,
|
||||
amount?: bigint
|
||||
) => {
|
||||
const { client, chainId } = useUnstableProvider()
|
||||
const metadata = useMetadata()
|
||||
|
||||
const { data: calldata } = useSWR(
|
||||
client && chainId && networkId && sessionIndex && transactionHash && receiver && amount && metadata
|
||||
? ["self_applause", client, chainId, metadata, networkId, sessionIndex, transactionHash, receiver, amount]
|
||||
: null,
|
||||
([_, client, _chainId, metadata, networkId, sessionIndex, transactionHash, receiver, amount]) => {
|
||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||
const { codec, location } = builder.buildCall("GhostSlowClaps", "self_applause")
|
||||
|
||||
const txHash = new Binary(fromHex(transactionHash))
|
||||
return toHex(
|
||||
mergeUint8(
|
||||
new Uint8Array(location),
|
||||
codec.enc({
|
||||
network_id: BigInt(networkId?.toString() ?? "0"),
|
||||
prev_session_index: sessionIndex,
|
||||
transaction_hash: txHash,
|
||||
receiver: receiver,
|
||||
amount: amount,
|
||||
}),
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
return calldata
|
||||
}
|
||||
|
||||
51
src/hooks/useClapsInSession.tsx
Normal file
51
src/hooks/useClapsInSession.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import useSWRSubscription from "swr/subscription"
|
||||
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders"
|
||||
import type { BlockInfo } from "@polkadot-api/observable-client"
|
||||
import { distinct, filter, map, mergeMap } from "rxjs"
|
||||
|
||||
import { useUnstableProvider } from "./useUnstableProvider"
|
||||
import { useMetadata } from "./useMetadata"
|
||||
|
||||
export type SessionAuthorityInfo = {
|
||||
claps: number
|
||||
disabled: boolean
|
||||
}
|
||||
|
||||
interface ClapsInSessionInterface {
|
||||
currentSession?: Number;
|
||||
}
|
||||
|
||||
export const useClapsInSession = ({ currentSession }: ClapsInSessionInterface) => {
|
||||
const { chainHead$, chainId } = useUnstableProvider()
|
||||
const metadata = useMetadata()
|
||||
const { data: clapsInSession } = useSWRSubscription(
|
||||
chainHead$ && chainId && metadata
|
||||
? ["clapsInSession", chainHead$, currentSession, chainId, metadata]
|
||||
: null,
|
||||
([_, chainHead$, currentSession, chainId, metadata], { next }) => {
|
||||
const { finalized$, storage$ } = chainHead$
|
||||
const subscription = finalized$.pipe(
|
||||
filter(Boolean),
|
||||
mergeMap((blockInfo: BlockInfo) => {
|
||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||
const clapsInSession = builder.buildStorage("GhostSlowClaps", "ClapsInSession")
|
||||
return storage$(blockInfo?.hash, "value", () =>
|
||||
clapsInSession?.keys.enc(currentSession)
|
||||
).pipe(
|
||||
filter(Boolean),
|
||||
distinct(),
|
||||
map((value: string) => clapsInSession?.value.dec(value) as SessionAuthorityInfo)
|
||||
)
|
||||
}),
|
||||
)
|
||||
.subscribe({
|
||||
next(clapsInSession: SessionAuthorityInfo) {
|
||||
next(null, clapsInSession)
|
||||
},
|
||||
error: next,
|
||||
})
|
||||
return () => subscription.unsubscribe()
|
||||
}
|
||||
)
|
||||
return clapsInSession
|
||||
}
|
||||
@ -21,3 +21,21 @@ export const useExistentialDeposit = () => {
|
||||
)
|
||||
return existentialDeposit
|
||||
}
|
||||
|
||||
export const useApplauseThreshold = () => {
|
||||
const { chainId } = useUnstableProvider()
|
||||
const metadata = useMetadata()
|
||||
const { data: existentialDeposit } = useSWR(
|
||||
chainId && metadata
|
||||
? ["ApplauseThreshold", chainId, metadata]
|
||||
: null,
|
||||
([_, chainId, metadata]) => {
|
||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||
const codec = builder.buildConstant("GhostSlowClaps", "ApplauseThreshold")
|
||||
const constants = metadata?.pallets?.find(obj => obj.name === "GhostSlowClaps")?.constants
|
||||
const value = constants?.find(obj => obj.name === "ApplauseThreshold")?.value
|
||||
return value ? codec.dec(value) : undefined
|
||||
}
|
||||
)
|
||||
return existentialDeposit
|
||||
}
|
||||
|
||||
42
src/hooks/useCurrentIndex.tsx
Normal file
42
src/hooks/useCurrentIndex.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import useSWRSubscription from "swr/subscription"
|
||||
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders"
|
||||
import type { BlockInfo } from "@polkadot-api/observable-client"
|
||||
import { distinct, filter, map, mergeMap } from "rxjs"
|
||||
|
||||
import { useUnstableProvider } from "./useUnstableProvider"
|
||||
import { useMetadata } from "./useMetadata"
|
||||
|
||||
export const useCurrentIndex = () => {
|
||||
const { chainHead$, chainId } = useUnstableProvider()
|
||||
const metadata = useMetadata()
|
||||
const { data: currentIndex } = useSWRSubscription(
|
||||
chainHead$ && chainId && metadata
|
||||
? ["currentIndex", chainHead$, chainId, metadata]
|
||||
: null,
|
||||
([_, chainHead$, chainId, metadata], { next }) => {
|
||||
const { finalized$, storage$ } = chainHead$
|
||||
const subscription = finalized$.pipe(
|
||||
filter(Boolean),
|
||||
mergeMap((blockInfo: BlockInfo) => {
|
||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||
const currentIndex = builder.buildStorage("Session", "CurrentIndex")
|
||||
return storage$(blockInfo?.hash, "value", () =>
|
||||
currentIndex?.keys.enc()
|
||||
).pipe(
|
||||
filter(Boolean),
|
||||
distinct(),
|
||||
map((value: string) => currentIndex?.value.dec(value) as Number)
|
||||
)
|
||||
}),
|
||||
)
|
||||
.subscribe({
|
||||
next(currentIndex: Number) {
|
||||
next(null, currentIndex)
|
||||
},
|
||||
error: next,
|
||||
})
|
||||
return () => subscription.unsubscribe()
|
||||
}
|
||||
)
|
||||
return currentIndex
|
||||
}
|
||||
54
src/hooks/useReceivedClaps.tsx
Normal file
54
src/hooks/useReceivedClaps.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import useSWRSubscription from "swr/subscription"
|
||||
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders"
|
||||
import type { BlockInfo } from "@polkadot-api/observable-client"
|
||||
import { distinct, filter, map, mergeMap } from "rxjs"
|
||||
import { fromHex } from "@polkadot-api/utils";
|
||||
|
||||
import { useUnstableProvider } from "./useUnstableProvider"
|
||||
import { useMetadata } from "./useMetadata"
|
||||
|
||||
interface ReceivedClapsInterface {
|
||||
currentSession?: Number;
|
||||
txHash?: string;
|
||||
argsHash?: string;
|
||||
}
|
||||
|
||||
export const useReceivedClaps = ({ currentSession, txHash, argsHash }: ReceivedClapsInterface) => {
|
||||
const { chainHead$, chainId } = useUnstableProvider()
|
||||
const metadata = useMetadata()
|
||||
const { data: receivedClaps } = useSWRSubscription(
|
||||
chainHead$ && txHash && argsHash && currentSession && chainId && metadata
|
||||
? ["receivedClaps", chainHead$, txHash, argsHash, currentSession, chainId, metadata]
|
||||
: null,
|
||||
([_, chainHead$, txHash, argsHash, currentSession, chainId, metadata], { next }) => {
|
||||
const { finalized$, storage$ } = chainHead$
|
||||
const subscription = finalized$.pipe(
|
||||
filter(Boolean),
|
||||
mergeMap((blockInfo: BlockInfo) => {
|
||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||
const receivedClaps = builder.buildStorage("GhostSlowClaps", "ReceivedClaps")
|
||||
|
||||
return storage$(blockInfo?.hash, "value", () =>
|
||||
receivedClaps?.keys.enc(
|
||||
currentSession,
|
||||
{ asBytes: () => fromHex(txHash) },
|
||||
{ asBytes: () => fromHex(argsHash) },
|
||||
)
|
||||
).pipe(
|
||||
filter(Boolean),
|
||||
distinct(),
|
||||
map((value: string) => receivedClaps?.value.dec(value) as Number[])
|
||||
)
|
||||
}),
|
||||
)
|
||||
.subscribe({
|
||||
next(receivedClaps: Number[]) {
|
||||
next(null, receivedClaps)
|
||||
},
|
||||
error: next,
|
||||
})
|
||||
return () => subscription.unsubscribe()
|
||||
}
|
||||
)
|
||||
return receivedClaps
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user