feat: validate and dry-run transactions (#162)
* refactor: break down SubmitTx into separate files * add validate transaction, start dry run * add dry run * fix worker getting stuck after forklift is disposed * handle rejections in promiseWithTeardown
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.1.0-autogenerated.8494276640227355333",
|
||||
"version": "0.1.0-autogenerated.3203825568190824154",
|
||||
"name": "@polkadot-api/descriptors",
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
+1
-1
@@ -14,5 +14,5 @@ export const whitelist: WhitelistEntriesByChain = {
|
||||
"query.Session.CurrentIndex",
|
||||
"api.TransactionPaymentApi.query_info",
|
||||
],
|
||||
dotAh: ["query.*", "tx.*", "const.*"],
|
||||
dotAh: ["query.*", "tx.*", "const.*", "api.*"],
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@paraspell/sdk": "^13.7.2",
|
||||
"@polkadot-api/descriptors": "file:.papi/descriptors",
|
||||
"@polkadot-api/forklift": "^0.3.0",
|
||||
"@polkadot-api/json-rpc-provider-proxy": "^0.4.0",
|
||||
"@polkadot-api/metadata-builders": "^0.14.3",
|
||||
"@polkadot-api/observable-client": "^0.18.7",
|
||||
|
||||
Generated
+449
-14
@@ -28,6 +28,9 @@ importers:
|
||||
'@polkadot-api/descriptors':
|
||||
specifier: file:.papi/descriptors
|
||||
version: file:.papi/descriptors(polkadot-api@2.1.6(bufferutil@4.1.0)(esbuild@0.25.12)(rxjs@7.8.2))
|
||||
'@polkadot-api/forklift':
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0(@react-rxjs/core@0.10.8(react@19.2.7)(rxjs@7.8.2))(bufferutil@4.1.0)(esbuild@0.25.12)(react@19.2.7)(typescript@6.0.3)
|
||||
'@polkadot-api/json-rpc-provider-proxy':
|
||||
specifier: ^0.4.0
|
||||
version: 0.4.0
|
||||
@@ -157,7 +160,7 @@ importers:
|
||||
version: 10.0.1(eslint@10.5.0(jiti@2.7.0))
|
||||
'@tailwindcss/vite':
|
||||
specifier: ^4.3.1
|
||||
version: 4.3.1(vite@8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.6.1))
|
||||
version: 4.3.1(vite@8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.9.0))
|
||||
'@types/node':
|
||||
specifier: ^25.9.3
|
||||
version: 25.9.3
|
||||
@@ -172,7 +175,7 @@ importers:
|
||||
version: 4.0.7
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2(vite@8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.6.1))
|
||||
version: 6.0.2(vite@8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.9.0))
|
||||
eslint:
|
||||
specifier: ^10.5.0
|
||||
version: 10.5.0(jiti@2.7.0)
|
||||
@@ -199,7 +202,7 @@ importers:
|
||||
version: 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)
|
||||
vite:
|
||||
specifier: ^8.0.16
|
||||
version: 8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.6.1)
|
||||
version: 8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.9.0)
|
||||
|
||||
packages:
|
||||
|
||||
@@ -686,6 +689,10 @@ packages:
|
||||
resolution: {integrity: sha512-VcTfNrzIf6acMSbBlmnyTWsR4KIMGc/QmIzGzIUne+Qj145H7BkYJ7Rvr7dG92tK+eT7Keack+CJME6pjPXcLQ==}
|
||||
hasBin: true
|
||||
|
||||
'@polkadot-api/cli@0.21.6':
|
||||
resolution: {integrity: sha512-1OQ2LvRSHkUcT4WRvLQFJ5PhLLN1Z1o6X1c7dguWW3eZ0bv7I9PWrbE5AyyXcy/jkceKCQ6HyISsfbBv8tIQmw==}
|
||||
hasBin: true
|
||||
|
||||
'@polkadot-api/codegen@0.22.5':
|
||||
resolution: {integrity: sha512-zwZJAlviI211zhj5i6oXkrr0crrbO3GZjBd2vC9AshY1pRmyiNLV9DZsXw4E6l4JQwdAAyNWtPdnvvB9T3TpKg==}
|
||||
|
||||
@@ -694,6 +701,12 @@ packages:
|
||||
peerDependencies:
|
||||
polkadot-api: '>=2.0.0'
|
||||
|
||||
'@polkadot-api/forklift@0.3.0':
|
||||
resolution: {integrity: sha512-cMi/K5yR0RI55SaMS9l+xgshlhDyxg4cftl+Hgnmgdjxx9NKHTcXRt34HxAPTk2IMqAJ+0W2FPW1JSLt5tFLgA==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
typescript: ^6.0.3
|
||||
|
||||
'@polkadot-api/ink-contracts@0.6.3':
|
||||
resolution: {integrity: sha512-XqnM1VDzI5L62xgg+f8le2yEoz8QZbUKEfAfPnHMOgBj9tJiyF15FcOJmnLMO/vq3cGixqh18tzJekLG5YTxtA==}
|
||||
|
||||
@@ -712,6 +725,9 @@ packages:
|
||||
'@polkadot-api/known-chains@0.11.5':
|
||||
resolution: {integrity: sha512-KOVQRyZj43lr1W5w1lZpzzLUszjPPGV32USsGVxFdguWG7L/gH+nHyBPkyhw3GhN+8NMQD7ZCyuMuNKXbRYlDA==}
|
||||
|
||||
'@polkadot-api/known-chains@0.11.6':
|
||||
resolution: {integrity: sha512-EEffAbSELaYgUjZN1oiPQuJLshI0kuepr+QcT3Z28CQFRfCfSvhLTI0YE4keJ43b8TnqK5VvE8g4fW/rZqTxoA==}
|
||||
|
||||
'@polkadot-api/ledger-signer@0.3.3':
|
||||
resolution: {integrity: sha512-kb1AvGu0m0d0IDXvcXzPPwJ8+Lmx7wPQ/VzuBKPZyZWyKk6RM8Zdxnp+v15eHpdmrUvmz//BtPbId01wJmLD2Q==}
|
||||
peerDependencies:
|
||||
@@ -1616,139 +1632,277 @@ packages:
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.62.2':
|
||||
resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-android-arm64@4.62.0':
|
||||
resolution: {integrity: sha512-M6s9cr10MibETyo8JsOkq+Lo1+lU6hcvb1MApnUql5qte/5hMEgzlN8/ReIKNfRV8rrqX50W1BX9zoUhC192RA==}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-android-arm64@4.62.2':
|
||||
resolution: {integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.62.0':
|
||||
resolution: {integrity: sha512-BqCoMoIbn0keKys+dEAdBa70EtOwV1bEsQCUgU9FdiZmmMge/Zk7LlkYGqbrdHR+Frnt0E1FOanly+rlwvvQzw==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.62.2':
|
||||
resolution: {integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.62.0':
|
||||
resolution: {integrity: sha512-SIMzST3VFNXDAbeIWDWiFCNM5qncUBDWaEV7NfE7oZbDt2mgfW4MvbKdbYiGOLoM32gbTv608UMd0XktEYSD7w==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.62.2':
|
||||
resolution: {integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.62.0':
|
||||
resolution: {integrity: sha512-ezjfSQMP7ArdUsbBwbQIfwAlhE84I2iVnzQNCFSveqV42q+BmKlzVpf7mxv5EchLcoWU4y6/heFzVg1F+hodUQ==}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.62.2':
|
||||
resolution: {integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.62.0':
|
||||
resolution: {integrity: sha512-9+qTWGW9AZRhnUgwtTwzNwcPlL87ngkeN0LA+q1bADvmY9aNvWaF2TFW8BZgnQPYxpDI7+rMVLivcd4V737TAQ==}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.62.2':
|
||||
resolution: {integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.62.0':
|
||||
resolution: {integrity: sha512-T1dMEQhXA/jkJ/jyMIw9IovK8bSUq7A8kLIlvZTb/6YIVsp2zLavr4F3oyllHWo7eIVJRyE5n3tUjQJEbE1IuQ==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.62.2':
|
||||
resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.62.0':
|
||||
resolution: {integrity: sha512-2as0LgT7qQpyceQq6VUJYnumUMUrgGQCWIiDIN9DE0/tglsk6o66uCB4f3djRawAltvfCNLyZZrsqbPA6inCsA==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.62.2':
|
||||
resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.62.0':
|
||||
resolution: {integrity: sha512-bVURMg+6eNN9C/yc0aVjooZcwTTtYF4YW3xta5pP0//r3o1V8gXEHXWCndj47w/HhwsFroZrFhR+6uQP5T0n0g==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.62.0':
|
||||
resolution: {integrity: sha512-Ful8pM/2yYI83PViWdFdpZhdI8HJ5qsXANe5atypbHDf+KIBBDsZsbyy8hbXnULVvW9NsTh5DHwbcBftyLTfiw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.62.2':
|
||||
resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.62.0':
|
||||
resolution: {integrity: sha512-9Gp/DgrkzfUBmNPVTyPTvay+4xEP7M/clXpj3efXBcm6uTIVIgDg4rqUpqKXvLEuFRVuEpSAOkhgNeecvaZ4Cg==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.62.0':
|
||||
resolution: {integrity: sha512-m9tsJz54LUXkSYM8+8PG81B9IKK5r+2T0clMq4QrS16xFosufU7firBDAZEsDheDs7wTlP7h3++S7lMsU955HA==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.62.2':
|
||||
resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.62.0':
|
||||
resolution: {integrity: sha512-3UvJ5PNVU16aJf6M3tFI24pWzAl2/ynfbyRN3ICyQajK1lSkrnVYNnLz3v04J32qKa0FczJc22zeToc0lr2A3w==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.62.0':
|
||||
resolution: {integrity: sha512-vRWUAbYLGHBZS6Q8Msb2sfnf1fvJf+47t8l/TwOerM2qArzy+IeNMTHrYLHXh95h8MoatPHI5hhSZNs+mGXKPg==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.62.2':
|
||||
resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.62.0':
|
||||
resolution: {integrity: sha512-c00T5SYENHAt86cfW47URaP3Us5vLC/4QO7GYud1G5VNRffCwwCuBspwqYrriuJB+5m0WFzClCn9wed0FBjKvg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.62.0':
|
||||
resolution: {integrity: sha512-krrCDilhXOwFkSkO3Wm9I/f9H0L92XHHwy2fwxjukxIbh0dem8gZqOW5Y8BsHrpJv5qwlRBV+Wl4ZFyRWhUpwg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.62.2':
|
||||
resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.62.0':
|
||||
resolution: {integrity: sha512-7pfYFSTc4/rUC/FtAI0Qp6QthDBCIi6/AuP1xYqFk5vanI6KnL5dWKP60OM/05LOsbwTmIcvr6eXC4CJuJ75IA==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.62.0':
|
||||
resolution: {integrity: sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.62.0':
|
||||
resolution: {integrity: sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.62.2':
|
||||
resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.62.0':
|
||||
resolution: {integrity: sha512-3oVS7FLGa4U1qcvao9ylGxrjXZyUQqR8UwxEcnUEyPX53O/C/mKDZegNXTdHCP+h3e6ta/f1EN38Yif1mmZHYg==}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.62.2':
|
||||
resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.62.0':
|
||||
resolution: {integrity: sha512-yTB9TgfWj5wHe5QgktAgXTLLot1gvEjl1NiPPAUiCs4oPrIWFl5V4nC3GrkNdj9LaAU4s94nVrGbGOCqUpyWsg==}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.62.2':
|
||||
resolution: {integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.62.0':
|
||||
resolution: {integrity: sha512-5LOhoaesY3doG1c+ac/2JtgREpKoJr5bUHH8tKY0V8di7+uSV6BwLs2PlR0/yzefGOkR+wE7ZolZphHCsyG5Rw==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.62.2':
|
||||
resolution: {integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.62.0':
|
||||
resolution: {integrity: sha512-yYkWHhmbhRTWTnWos5HC4GcPQfjlzzCNbM9e/+GXrLuaBXYA3qSDR9f0Vgufd5S8yX81U8jPKp7ZnAjZFMtRnw==}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.62.2':
|
||||
resolution: {integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.62.0':
|
||||
resolution: {integrity: sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.62.0':
|
||||
resolution: {integrity: sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.62.2':
|
||||
resolution: {integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rx-state/core@0.1.4':
|
||||
resolution: {integrity: sha512-Z+3hjU2xh1HisLxt+W5hlYX/eGSDaXXP+ns82gq/PLZpkXLu0uwcNUh9RLY3Clq4zT+hSsA3vcpIGt6+UAb8rQ==}
|
||||
peerDependencies:
|
||||
@@ -2289,6 +2443,9 @@ packages:
|
||||
'@types/node@25.9.3':
|
||||
resolution: {integrity: sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==}
|
||||
|
||||
'@types/node@25.9.4':
|
||||
resolution: {integrity: sha512-dszCsrKb5U7ZsVZBWiHFklTloVl0mSEnWH/iZXfZUlI4rzCUnsvGmgqfuVRHL54ugE7/wRuxEIXRa2iMZ+BG6g==}
|
||||
|
||||
'@types/normalize-package-data@2.4.4':
|
||||
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
|
||||
|
||||
@@ -2309,6 +2466,9 @@ packages:
|
||||
'@types/trusted-types@2.0.7':
|
||||
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||
|
||||
'@types/ws@8.18.1':
|
||||
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.61.0':
|
||||
resolution: {integrity: sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
@@ -3421,6 +3581,10 @@ packages:
|
||||
resolution: {integrity: sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
ora@9.4.1:
|
||||
resolution: {integrity: sha512-6VlU9MLXbjVQD04AZCMX28hVtA5bUoadvUqO76MUCVA0ilwJbMiHsITRPfyVm6p/BC0Av/BXMujx39WCe1LEqw==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
ox@0.14.29:
|
||||
resolution: {integrity: sha512-M5j87Ec4V99MQdRct/g09eWXW60g6zhHTUs1lr4deUtrPDnezBdCJTgKd7pxqTpSZBFveV0ALi9jMMuT1qKyNg==}
|
||||
peerDependencies:
|
||||
@@ -3516,6 +3680,10 @@ packages:
|
||||
resolution: {integrity: sha512-eI9pKwWEix40kfvSzqEP6ldqOoBIN7dwD/o91TY5z8vQI12sAffpR/pOqAD1IVVwIVHDpHjkq0joBPdJD0rafA==}
|
||||
hasBin: true
|
||||
|
||||
pino@10.3.1:
|
||||
resolution: {integrity: sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==}
|
||||
hasBin: true
|
||||
|
||||
pino@9.14.0:
|
||||
resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==}
|
||||
hasBin: true
|
||||
@@ -3530,6 +3698,12 @@ packages:
|
||||
peerDependencies:
|
||||
rxjs: '>=7.8.0'
|
||||
|
||||
polkadot-api@2.1.7:
|
||||
resolution: {integrity: sha512-hSXzpbxtm4DkgBxC1m3ahqCiGTnOI75NmkWOJHlqgR3jmFYzPCMjuURpe8V1gKxzcDWMcffEmgwsM/4nm1Ox5Q==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
rxjs: '>=7.8.0'
|
||||
|
||||
polkahub@0.7.0:
|
||||
resolution: {integrity: sha512-qFSMsARaJmzjWZCF4L9EHNhKkZr995dUDw/tAYPKgwsayo8mOA+xCcYH7eJzoZOZsY2LAM4KLgM4acY1Ptt5bA==}
|
||||
peerDependencies:
|
||||
@@ -3689,6 +3863,9 @@ packages:
|
||||
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
|
||||
engines: {node: '>= 12.13.0'}
|
||||
|
||||
real-require@1.0.0:
|
||||
resolution: {integrity: sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g==}
|
||||
|
||||
require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -3720,6 +3897,11 @@ packages:
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
rollup@4.62.2:
|
||||
resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
rxjs@7.8.2:
|
||||
resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
|
||||
|
||||
@@ -3865,6 +4047,10 @@ packages:
|
||||
thread-stream@3.2.0:
|
||||
resolution: {integrity: sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==}
|
||||
|
||||
thread-stream@4.2.0:
|
||||
resolution: {integrity: sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
tinyglobby@0.2.17:
|
||||
resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@@ -4200,9 +4386,9 @@ packages:
|
||||
yallist@3.1.1:
|
||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||
|
||||
yaml@2.6.1:
|
||||
resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==}
|
||||
engines: {node: '>= 14'}
|
||||
yaml@2.9.0:
|
||||
resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
|
||||
engines: {node: '>= 14.6'}
|
||||
hasBin: true
|
||||
|
||||
yargs-parser@18.1.3:
|
||||
@@ -4806,6 +4992,41 @@ snapshots:
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@polkadot-api/cli@0.21.6(bufferutil@4.1.0)(esbuild@0.25.12)':
|
||||
dependencies:
|
||||
'@commander-js/extra-typings': 15.0.0(commander@15.0.0)
|
||||
'@polkadot-api/codegen': 0.22.5
|
||||
'@polkadot-api/ink-contracts': 0.6.3
|
||||
'@polkadot-api/json-rpc-provider': 0.2.0
|
||||
'@polkadot-api/known-chains': 0.11.6
|
||||
'@polkadot-api/metadata-compatibility': 0.6.3
|
||||
'@polkadot-api/observable-client': 0.18.7(rxjs@7.8.2)
|
||||
'@polkadot-api/sm-provider': 0.3.6(@polkadot-api/smoldot@0.4.5(bufferutil@4.1.0))
|
||||
'@polkadot-api/smoldot': 0.4.5(bufferutil@4.1.0)
|
||||
'@polkadot-api/substrate-bindings': 0.20.3
|
||||
'@polkadot-api/substrate-client': 0.7.0
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
'@polkadot-api/wasm-executor': 0.2.3
|
||||
'@polkadot-api/ws-middleware': 0.3.5(rxjs@7.8.2)
|
||||
'@polkadot-api/ws-provider': 0.9.0(rxjs@7.8.2)
|
||||
'@types/node': 25.9.4
|
||||
commander: 15.0.0
|
||||
execa: 9.6.1
|
||||
fs.promises.exists: 1.1.4
|
||||
ora: 9.4.1
|
||||
read-pkg: 10.1.0
|
||||
rollup: 4.62.2
|
||||
rollup-plugin-esbuild: 6.2.1(esbuild@0.25.12)(rollup@4.62.2)
|
||||
rxjs: 7.8.2
|
||||
tsc-prog: 2.3.0(typescript@6.0.3)
|
||||
typescript: 6.0.3
|
||||
write-package: 7.2.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- esbuild
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@polkadot-api/codegen@0.22.5':
|
||||
dependencies:
|
||||
'@polkadot-api/ink-contracts': 0.6.3
|
||||
@@ -4818,6 +5039,35 @@ snapshots:
|
||||
dependencies:
|
||||
polkadot-api: 2.1.6(bufferutil@4.1.0)(esbuild@0.25.12)(rxjs@7.8.2)
|
||||
|
||||
'@polkadot-api/forklift@0.3.0(@react-rxjs/core@0.10.8(react@19.2.7)(rxjs@7.8.2))(bufferutil@4.1.0)(esbuild@0.25.12)(react@19.2.7)(typescript@6.0.3)':
|
||||
dependencies:
|
||||
'@acala-network/chopsticks-executor': 1.4.2
|
||||
'@polkadot-api/metadata-builders': 0.14.3
|
||||
'@polkadot-api/observable-client': 0.18.7(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.20.3
|
||||
'@polkadot-api/substrate-client': 0.7.0
|
||||
'@polkadot-api/tx-utils': 0.3.3
|
||||
'@polkadot-api/ws-middleware': 0.3.5(rxjs@7.8.2)
|
||||
'@polkadot-api/ws-provider': 0.9.0(rxjs@7.8.2)
|
||||
'@react-rxjs/utils': 0.9.7(@react-rxjs/core@0.10.8(react@19.2.7)(rxjs@7.8.2))(react@19.2.7)(rxjs@7.8.2)
|
||||
'@types/ws': 8.18.1
|
||||
comlink: 4.4.2
|
||||
commander: 15.0.0
|
||||
pino: 10.3.1
|
||||
pino-pretty: 13.1.3
|
||||
polkadot-api: 2.1.7(bufferutil@4.1.0)(esbuild@0.25.12)(rxjs@7.8.2)
|
||||
rxjs: 7.8.2
|
||||
typescript: 6.0.3
|
||||
ws: 8.21.0(bufferutil@4.1.0)
|
||||
yaml: 2.9.0
|
||||
transitivePeerDependencies:
|
||||
- '@react-rxjs/core'
|
||||
- bufferutil
|
||||
- esbuild
|
||||
- react
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@polkadot-api/ink-contracts@0.6.3':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.14.3
|
||||
@@ -4836,6 +5086,8 @@ snapshots:
|
||||
|
||||
'@polkadot-api/known-chains@0.11.5': {}
|
||||
|
||||
'@polkadot-api/known-chains@0.11.6': {}
|
||||
|
||||
'@polkadot-api/ledger-signer@0.3.3(@ledgerhq/hw-transport@6.35.4)':
|
||||
dependencies:
|
||||
'@ledgerhq/hw-transport': 6.35.4
|
||||
@@ -6384,78 +6636,153 @@ snapshots:
|
||||
'@rollup/rollup-android-arm-eabi@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm64@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.62.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rx-state/core@0.1.4(rxjs@7.8.2)':
|
||||
dependencies:
|
||||
rxjs: 7.8.2
|
||||
@@ -7080,12 +7407,12 @@ snapshots:
|
||||
'@tailwindcss/oxide-win32-arm64-msvc': 4.3.1
|
||||
'@tailwindcss/oxide-win32-x64-msvc': 4.3.1
|
||||
|
||||
'@tailwindcss/vite@4.3.1(vite@8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.6.1))':
|
||||
'@tailwindcss/vite@4.3.1(vite@8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.9.0))':
|
||||
dependencies:
|
||||
'@tailwindcss/node': 4.3.1
|
||||
'@tailwindcss/oxide': 4.3.1
|
||||
tailwindcss: 4.3.1
|
||||
vite: 8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.6.1)
|
||||
vite: 8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.9.0)
|
||||
|
||||
'@tanem/svg-injector@11.3.2':
|
||||
dependencies:
|
||||
@@ -7112,6 +7439,10 @@ snapshots:
|
||||
dependencies:
|
||||
undici-types: 7.24.6
|
||||
|
||||
'@types/node@25.9.4':
|
||||
dependencies:
|
||||
undici-types: 7.24.6
|
||||
|
||||
'@types/normalize-package-data@2.4.4': {}
|
||||
|
||||
'@types/prop-types@15.7.15': {}
|
||||
@@ -7130,6 +7461,10 @@ snapshots:
|
||||
|
||||
'@types/trusted-types@2.0.7': {}
|
||||
|
||||
'@types/ws@8.18.1':
|
||||
dependencies:
|
||||
'@types/node': 25.9.3
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
@@ -7221,10 +7556,10 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.61.0
|
||||
eslint-visitor-keys: 5.0.1
|
||||
|
||||
'@vitejs/plugin-react@6.0.2(vite@8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.6.1))':
|
||||
'@vitejs/plugin-react@6.0.2(vite@8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.9.0))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.1
|
||||
vite: 8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.6.1)
|
||||
vite: 8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.9.0)
|
||||
|
||||
'@wallet-standard/base@1.1.1': {}
|
||||
|
||||
@@ -8520,6 +8855,17 @@ snapshots:
|
||||
stdin-discarder: 0.3.2
|
||||
string-width: 8.2.1
|
||||
|
||||
ora@9.4.1:
|
||||
dependencies:
|
||||
chalk: 5.6.2
|
||||
cli-cursor: 5.0.0
|
||||
cli-spinners: 3.4.0
|
||||
is-interactive: 2.0.0
|
||||
is-unicode-supported: 2.1.0
|
||||
log-symbols: 7.0.1
|
||||
stdin-discarder: 0.3.2
|
||||
string-width: 8.2.1
|
||||
|
||||
ox@0.14.29(typescript@6.0.3)(zod@3.22.4):
|
||||
dependencies:
|
||||
'@adraffy/ens-normalize': 1.11.1
|
||||
@@ -8660,6 +9006,20 @@ snapshots:
|
||||
sonic-boom: 4.2.1
|
||||
thread-stream: 3.2.0
|
||||
|
||||
pino@10.3.1:
|
||||
dependencies:
|
||||
'@pinojs/redact': 0.4.0
|
||||
atomic-sleep: 1.0.0
|
||||
on-exit-leak-free: 2.1.2
|
||||
pino-abstract-transport: 3.0.0
|
||||
pino-std-serializers: 7.1.0
|
||||
process-warning: 5.0.0
|
||||
quick-format-unescaped: 4.0.4
|
||||
real-require: 0.2.0
|
||||
safe-stable-stringify: 2.5.0
|
||||
sonic-boom: 4.2.1
|
||||
thread-stream: 4.2.0
|
||||
|
||||
pino@9.14.0:
|
||||
dependencies:
|
||||
'@pinojs/redact': 0.4.0
|
||||
@@ -8704,6 +9064,34 @@ snapshots:
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
polkadot-api@2.1.7(bufferutil@4.1.0)(esbuild@0.25.12)(rxjs@7.8.2):
|
||||
dependencies:
|
||||
'@polkadot-api/cli': 0.21.6(bufferutil@4.1.0)(esbuild@0.25.12)
|
||||
'@polkadot-api/ink-contracts': 0.6.3
|
||||
'@polkadot-api/json-rpc-provider': 0.2.0
|
||||
'@polkadot-api/known-chains': 0.11.6
|
||||
'@polkadot-api/logs-provider': 0.2.0
|
||||
'@polkadot-api/metadata-builders': 0.14.3
|
||||
'@polkadot-api/metadata-compatibility': 0.6.3
|
||||
'@polkadot-api/observable-client': 0.18.7(rxjs@7.8.2)
|
||||
'@polkadot-api/pjs-signer': 0.7.3
|
||||
'@polkadot-api/polkadot-signer': 0.1.6
|
||||
'@polkadot-api/signer': 0.3.3
|
||||
'@polkadot-api/sm-provider': 0.3.6(@polkadot-api/smoldot@0.4.5(bufferutil@4.1.0))
|
||||
'@polkadot-api/smoldot': 0.4.5(bufferutil@4.1.0)
|
||||
'@polkadot-api/substrate-bindings': 0.20.3
|
||||
'@polkadot-api/substrate-client': 0.7.0
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
'@polkadot-api/ws-middleware': 0.3.5(rxjs@7.8.2)
|
||||
'@polkadot-api/ws-provider': 0.9.0(rxjs@7.8.2)
|
||||
'@rx-state/core': 0.1.4(rxjs@7.8.2)
|
||||
rxjs: 7.8.2
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- esbuild
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
polkahub@0.7.0(@ledgerhq/hw-transport@6.35.4)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(bufferutil@4.1.0)(esbuild@0.25.12)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rxjs@7.8.2)(typescript@6.0.3)(use-sync-external-store@1.6.0(react@19.2.7))(zod@3.25.76):
|
||||
dependencies:
|
||||
'@polkahub/context': 0.6.0(@types/react@19.2.17)(bufferutil@4.1.0)(esbuild@0.25.12)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||
@@ -8906,6 +9294,8 @@ snapshots:
|
||||
|
||||
real-require@0.2.0: {}
|
||||
|
||||
real-require@1.0.0: {}
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
require-main-filename@2.0.0: {}
|
||||
@@ -8949,6 +9339,17 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
rollup-plugin-esbuild@6.2.1(esbuild@0.25.12)(rollup@4.62.2):
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
es-module-lexer: 1.7.0
|
||||
esbuild: 0.25.12
|
||||
get-tsconfig: 4.14.0
|
||||
rollup: 4.62.2
|
||||
unplugin-utils: 0.2.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
rollup@4.62.0:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.9
|
||||
@@ -8980,6 +9381,37 @@ snapshots:
|
||||
'@rollup/rollup-win32-x64-msvc': 4.62.0
|
||||
fsevents: 2.3.3
|
||||
|
||||
rollup@4.62.2:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.9
|
||||
optionalDependencies:
|
||||
'@rollup/rollup-android-arm-eabi': 4.62.2
|
||||
'@rollup/rollup-android-arm64': 4.62.2
|
||||
'@rollup/rollup-darwin-arm64': 4.62.2
|
||||
'@rollup/rollup-darwin-x64': 4.62.2
|
||||
'@rollup/rollup-freebsd-arm64': 4.62.2
|
||||
'@rollup/rollup-freebsd-x64': 4.62.2
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.62.2
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.62.2
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-arm64-musl': 4.62.2
|
||||
'@rollup/rollup-linux-loong64-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-loong64-musl': 4.62.2
|
||||
'@rollup/rollup-linux-ppc64-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-ppc64-musl': 4.62.2
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-riscv64-musl': 4.62.2
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-x64-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-x64-musl': 4.62.2
|
||||
'@rollup/rollup-openbsd-x64': 4.62.2
|
||||
'@rollup/rollup-openharmony-arm64': 4.62.2
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.62.2
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.62.2
|
||||
'@rollup/rollup-win32-x64-gnu': 4.62.2
|
||||
'@rollup/rollup-win32-x64-msvc': 4.62.2
|
||||
fsevents: 2.3.3
|
||||
|
||||
rxjs@7.8.2:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -9102,6 +9534,10 @@ snapshots:
|
||||
dependencies:
|
||||
real-require: 0.2.0
|
||||
|
||||
thread-stream@4.2.0:
|
||||
dependencies:
|
||||
real-require: 1.0.0
|
||||
|
||||
tinyglobby@0.2.17:
|
||||
dependencies:
|
||||
fdir: 6.5.0(picomatch@4.0.4)
|
||||
@@ -9262,7 +9698,7 @@ snapshots:
|
||||
- utf-8-validate
|
||||
- zod
|
||||
|
||||
vite@8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.6.1):
|
||||
vite@8.0.16(@types/node@25.9.3)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.9.0):
|
||||
dependencies:
|
||||
lightningcss: 1.32.0
|
||||
picomatch: 4.0.4
|
||||
@@ -9274,7 +9710,7 @@ snapshots:
|
||||
esbuild: 0.25.12
|
||||
fsevents: 2.3.3
|
||||
jiti: 2.7.0
|
||||
yaml: 2.6.1
|
||||
yaml: 2.9.0
|
||||
|
||||
web-streams-polyfill@3.3.3: {}
|
||||
|
||||
@@ -9337,8 +9773,7 @@ snapshots:
|
||||
|
||||
yallist@3.1.1: {}
|
||||
|
||||
yaml@2.6.1:
|
||||
optional: true
|
||||
yaml@2.9.0: {}
|
||||
|
||||
yargs-parser@18.1.3:
|
||||
dependencies:
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
import { ActionButton } from "@/components/ActionButton"
|
||||
import { JsonDisplay } from "@/components/JsonDisplay"
|
||||
import {
|
||||
Dialog,
|
||||
DialogBody,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog"
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip"
|
||||
import { SystemEvent } from "@polkadot-api/observable-client"
|
||||
import { state, useStateObservable } from "@react-rxjs/core"
|
||||
import { createSignal } from "@react-rxjs/utils"
|
||||
import { CheckCircle, CircleAlert, CircleX, Loader2, Play } from "lucide-react"
|
||||
import { FC, ReactNode, useEffect, useState } from "react"
|
||||
import { combineLatest, startWith, switchMap, takeUntil } from "rxjs"
|
||||
import { txValidity$ } from "./Estimates"
|
||||
import { transaction$, txOptions$ } from "./submit.state"
|
||||
import { dryRun$ } from "./validate"
|
||||
|
||||
const [triggerDryRun$, dryRun] = createSignal()
|
||||
const [cancelDryRun$, cancelDryRun] = createSignal()
|
||||
const dryRunResult$ = state(
|
||||
triggerDryRun$.pipe(
|
||||
switchMap(() =>
|
||||
combineLatest([transaction$, txOptions$]).pipe(
|
||||
switchMap(([tx, txOptions], idx) => {
|
||||
// any late change interrupts and cancels the dry run
|
||||
if (idx > 0 || !tx) return [null]
|
||||
|
||||
return dryRun$(tx, txOptions).pipe(
|
||||
startWith({
|
||||
type: "running" as const,
|
||||
value: undefined,
|
||||
}),
|
||||
)
|
||||
}),
|
||||
takeUntil(cancelDryRun$),
|
||||
),
|
||||
),
|
||||
),
|
||||
null,
|
||||
)
|
||||
|
||||
export const DryRun = () => {
|
||||
const validity = useStateObservable(txValidity$)
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const sub = dryRunResult$.subscribe()
|
||||
return () => sub.unsubscribe()
|
||||
}, [])
|
||||
|
||||
const disabled = validity?.type !== "valid"
|
||||
const button = (
|
||||
<ActionButton
|
||||
className="flex w-full items-center justify-center gap-2 rounded-md border border-border bg-background py-2.5 text-sm font-semibold text-foreground hover:bg-foreground/5"
|
||||
disabled={disabled}
|
||||
type="button"
|
||||
>
|
||||
<Play className="h-4 w-4" />
|
||||
Dry Run
|
||||
</ActionButton>
|
||||
)
|
||||
|
||||
return disabled ? (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div className="w-full cursor-default">{button}</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
Can only dry run transactions that have passed validation
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Dialog
|
||||
open={open}
|
||||
onOpenChange={(open) => {
|
||||
setOpen(open)
|
||||
if (open) {
|
||||
dryRun()
|
||||
} else {
|
||||
cancelDryRun()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DialogTrigger asChild>{button}</DialogTrigger>
|
||||
<DialogContent className="max-w-3xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Dry Run</DialogTitle>
|
||||
</DialogHeader>
|
||||
<DialogBody className="space-y-4">
|
||||
<DryRunModalContent />
|
||||
</DialogBody>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
const DryRunModalContent: FC = () => {
|
||||
const result = useStateObservable(dryRunResult$)
|
||||
if (!result || result.type === "no-signer") {
|
||||
// Should be unreachable
|
||||
return null
|
||||
}
|
||||
|
||||
if (result.type === "running") {
|
||||
return (
|
||||
<div className="flex items-center gap-3 rounded-md border border-dashed border-border bg-background/60 p-4 text-sm text-muted-foreground">
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
Simulating
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (result.type === "invalid" || result.type === "error") {
|
||||
return (
|
||||
<div
|
||||
className="rounded-md border border-red-500/30 bg-red-500/5 p-4 text-red-700 dark:text-red-300"
|
||||
role="alert"
|
||||
>
|
||||
<div className="flex items-start gap-2">
|
||||
<CircleAlert className="mt-0.5 h-4 w-4 shrink-0" />
|
||||
<div className="min-w-0 space-y-2">
|
||||
<div className="text-sm font-medium">
|
||||
Rejected by transaction validation
|
||||
</div>
|
||||
<div className="text-sm">
|
||||
<JsonDisplay src={result.value} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const { ok, dispatchError, events } = result.value
|
||||
const passed = ok && !dispatchError
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div
|
||||
className={
|
||||
passed
|
||||
? "rounded-md border border-emerald-500/30 bg-emerald-500/5 p-4"
|
||||
: "rounded-md border border-red-500/30 bg-red-500/5 p-4"
|
||||
}
|
||||
>
|
||||
<div className="flex items-start gap-2">
|
||||
{passed ? (
|
||||
<CheckCircle className="mt-0.5 h-4 w-4 shrink-0 text-emerald-600 dark:text-emerald-300" />
|
||||
) : (
|
||||
<CircleX className="mt-0.5 h-4 w-4 shrink-0 text-red-600 dark:text-red-300" />
|
||||
)}
|
||||
<div>
|
||||
<div className="text-sm font-medium">
|
||||
{passed ? "Transaction succeeded" : "Transaction failed"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{dispatchError ? (
|
||||
<DryRunSection title="Dispatch Error">
|
||||
<JsonDisplay src={dispatchError} />
|
||||
</DryRunSection>
|
||||
) : null}
|
||||
|
||||
<DryRunSection title="Events">
|
||||
<ol className="divide-y divide-border rounded-md border border-border">
|
||||
{events.map((event, index) => (
|
||||
<DryRunEvent key={index} event={event} />
|
||||
))}
|
||||
</ol>
|
||||
</DryRunSection>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const DryRunSection: FC<{ title: string; children: ReactNode }> = ({
|
||||
title,
|
||||
children,
|
||||
}) => (
|
||||
<section className="space-y-2">
|
||||
<h3 className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
|
||||
{title}
|
||||
</h3>
|
||||
{children}
|
||||
</section>
|
||||
)
|
||||
|
||||
type FlattenedEvent = SystemEvent & SystemEvent["event"]
|
||||
const DryRunEvent: FC<{ event: FlattenedEvent }> = ({ event }) => {
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
const eventName = getEventName(event)
|
||||
|
||||
return (
|
||||
<li>
|
||||
<button
|
||||
className="flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-sm hover:bg-foreground/5"
|
||||
type="button"
|
||||
onClick={() => setExpanded((v) => !v)}
|
||||
>
|
||||
<span className="min-w-0 truncate font-mono">{eventName}</span>
|
||||
</button>
|
||||
{expanded ? (
|
||||
<div className="max-h-80 overflow-auto border-t border-border px-3 py-2 bg-foreground/5">
|
||||
<JsonDisplay src={event.value.value} />
|
||||
</div>
|
||||
) : null}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
const getEventName = (event: FlattenedEvent) => {
|
||||
const pallet = event.type
|
||||
const name = event.value.type
|
||||
return `${pallet}.${name}`
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
import { TokenAmount } from "@/components/TokenAmount"
|
||||
import { client$ } from "@/state/chains/chain.state"
|
||||
import {
|
||||
getAccountGenericAddress,
|
||||
getAccountPublicKey,
|
||||
selectedAccount$,
|
||||
} from "@/state/polkahub"
|
||||
import { polkadot_people } from "@polkadot-api/descriptors"
|
||||
import {
|
||||
liftSuspense,
|
||||
state,
|
||||
SUSPENSE,
|
||||
useStateObservable,
|
||||
} from "@react-rxjs/core"
|
||||
import { switchMapSuspended } from "@react-rxjs/utils"
|
||||
import { CheckCircle, CircleX, Loader2 } from "lucide-react"
|
||||
import { FC, ReactNode } from "react"
|
||||
import { catchError, combineLatest, map, of, switchMap, timer } from "rxjs"
|
||||
import { transaction$, txOptions$ } from "./submit.state"
|
||||
import { validate$ } from "./validate"
|
||||
|
||||
const accountBalance$ = state(
|
||||
combineLatest([selectedAccount$, client$]).pipe(
|
||||
switchMapSuspended(([account, client]) =>
|
||||
account
|
||||
? client
|
||||
.getTypedApi(polkadot_people)
|
||||
.query.System.Account.getValue(getAccountGenericAddress(account))
|
||||
: [],
|
||||
),
|
||||
liftSuspense(),
|
||||
map((v) => (v === SUSPENSE ? null : v)),
|
||||
map((v) => {
|
||||
if (!v) return null
|
||||
const { reserved, free, frozen } = v.data
|
||||
const total = reserved + free
|
||||
|
||||
// TODO ED
|
||||
const untouchable = total == 0n ? 0n : maxBigInt(frozen - reserved, 0n)
|
||||
|
||||
return free - untouchable
|
||||
}),
|
||||
),
|
||||
null,
|
||||
)
|
||||
|
||||
export const paymentInfo$ = state(
|
||||
combineLatest([transaction$, selectedAccount$, txOptions$]).pipe(
|
||||
switchMapSuspended(([tx, account, txOptions]) => {
|
||||
if (!tx || !account) return [null]
|
||||
|
||||
// Adding a small delay for debouncing quick input changes
|
||||
return timer(200).pipe(
|
||||
switchMap(() =>
|
||||
tx.getPaymentInfo(getAccountPublicKey(account), txOptions),
|
||||
),
|
||||
catchError((ex) => {
|
||||
console.error(ex)
|
||||
return of(null)
|
||||
}),
|
||||
)
|
||||
}),
|
||||
liftSuspense(),
|
||||
map((v) => (v === SUSPENSE ? null : v)),
|
||||
),
|
||||
null,
|
||||
)
|
||||
|
||||
export const txValidity$ = state(
|
||||
combineLatest({
|
||||
tx: transaction$,
|
||||
txOptions: txOptions$,
|
||||
}).pipe(
|
||||
switchMapSuspended(({ tx, txOptions }) =>
|
||||
tx ? timer(500).pipe(switchMap(() => validate$(tx, txOptions))) : [null],
|
||||
),
|
||||
liftSuspense(),
|
||||
map((v) => (v === SUSPENSE ? null : v)),
|
||||
),
|
||||
null,
|
||||
)
|
||||
|
||||
export const Estimates: FC = () => {
|
||||
const paymentInfo = useStateObservable(paymentInfo$)
|
||||
const balance = useStateObservable(accountBalance$)
|
||||
const validity = useStateObservable(txValidity$)
|
||||
|
||||
const loader = <Loader2 className="h-4 w-4 animate-spin" />
|
||||
const renderValidity = () => {
|
||||
if (!validity) return loader
|
||||
if (validity.type === "valid") {
|
||||
return (
|
||||
<div className="flex items-center gap-1 font-sans">
|
||||
Valid
|
||||
<CheckCircle size={20} className="text-green-600" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (validity.type === "invalid") {
|
||||
return (
|
||||
<div className="flex items-center gap-1 font-sans">
|
||||
{`Invalid: ${validity.value}`}
|
||||
<CircleX size={20} className="text-red-400" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return "N/A"
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="mx-4 space-y-3 border-t border-border py-4">
|
||||
<h3 className="text-sm font-medium">Submission</h3>
|
||||
<EstimateRow
|
||||
label="Estimated fee"
|
||||
value={
|
||||
paymentInfo ? (
|
||||
<TokenAmount>{paymentInfo.partial_fee}</TokenAmount>
|
||||
) : (
|
||||
loader
|
||||
)
|
||||
}
|
||||
/>
|
||||
<EstimateRow
|
||||
label="Account spendable balance"
|
||||
value={balance == null ? loader : <TokenAmount>{balance}</TokenAmount>}
|
||||
/>
|
||||
<EstimateRow label="Validity" value={renderValidity()} />
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
const EstimateRow: FC<{ label: string; value: ReactNode }> = ({
|
||||
label,
|
||||
value,
|
||||
}) => (
|
||||
<div className="flex items-start justify-between gap-3 py-1.5">
|
||||
<span className="text-sm text-muted-foreground">{label}</span>
|
||||
<span className="text-right font-mono text-sm">{value}</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
const maxBigInt = (a: bigint, b: bigint) => (a > b ? a : b)
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ActionButton } from "@/components/ActionButton"
|
||||
import { Spinner } from "@/components/Icons"
|
||||
import { TokenAmount } from "@/components/TokenAmount"
|
||||
import { Dialog, DialogTrigger } from "@/components/ui/dialog"
|
||||
import {
|
||||
Select,
|
||||
@@ -9,15 +8,9 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select"
|
||||
import { createState } from "@/lib/externalState"
|
||||
import { PolkahubModalBasedManagers } from "@/pages/Accounts/Providers"
|
||||
import { client$, unsafeApi$ } from "@/state/chains/chain.state"
|
||||
import {
|
||||
getAccountGenericAddress,
|
||||
getAccountPublicKey,
|
||||
selectedAccount$,
|
||||
} from "@/state/polkahub"
|
||||
import { polkadot_people } from "@polkadot-api/descriptors"
|
||||
import { unsafeApi$ } from "@/state/chains/chain.state"
|
||||
import { getAccountGenericAddress, selectedAccount$ } from "@/state/polkahub"
|
||||
import {
|
||||
Button,
|
||||
DialogBody,
|
||||
@@ -33,13 +26,8 @@ import {
|
||||
useStateObservable,
|
||||
withDefault,
|
||||
} from "@react-rxjs/core"
|
||||
import {
|
||||
createSignal,
|
||||
mergeWithKey,
|
||||
switchMapSuspended,
|
||||
} from "@react-rxjs/utils"
|
||||
import { switchMapSuspended } from "@react-rxjs/utils"
|
||||
import { ChevronLeft, Send, Settings, WalletCards } from "lucide-react"
|
||||
import { TxOptions } from "polkadot-api"
|
||||
import {
|
||||
ModalContext,
|
||||
PjsWalletButtons,
|
||||
@@ -47,19 +35,23 @@ import {
|
||||
useSelectedAccount,
|
||||
} from "polkahub"
|
||||
import { FC, forwardRef, ReactNode, useState } from "react"
|
||||
import {
|
||||
catchError,
|
||||
combineLatest,
|
||||
distinctUntilChanged,
|
||||
map,
|
||||
of,
|
||||
scan,
|
||||
switchMap,
|
||||
timer,
|
||||
} from "rxjs"
|
||||
import { callData$ } from "../componentValue.state"
|
||||
import { catchError, map, switchMap, timer } from "rxjs"
|
||||
import { CustomSignedExt, customSignedExtensions$ } from "../CustomSignedExt"
|
||||
import { trackTx } from "../ExtrinsicsWorkspaceEntry"
|
||||
import { Estimates } from "./Estimates"
|
||||
import { DryRun } from "./DryRun"
|
||||
import {
|
||||
blurNonce,
|
||||
DEFAULT_MORTAL,
|
||||
mortality$,
|
||||
nonce$,
|
||||
setMortality,
|
||||
setNonce,
|
||||
setTip,
|
||||
tip$,
|
||||
transaction$,
|
||||
txOptions$,
|
||||
} from "./submit.state"
|
||||
import { SelectAccount } from "./SubmitTxForm"
|
||||
|
||||
const customExtensionsCount$ = state(
|
||||
@@ -76,8 +68,9 @@ const customExtensionsCount$ = state(
|
||||
null,
|
||||
)
|
||||
|
||||
const [nonceChanged$, setNonce] = createSignal<string>()
|
||||
const [nonceBlurred$, blurNonce] = createSignal()
|
||||
// powers of 2 from 4 to 16 (incl)
|
||||
const periodOptions = new Array(16 - 4 + 1).fill(0).map((_, i) => 1 << (i + 4))
|
||||
|
||||
const chainNonce$ = unsafeApi$.pipeState(
|
||||
switchMapSuspended((api) =>
|
||||
selectedAccount$.pipe(
|
||||
@@ -100,107 +93,6 @@ const chainNonce$ = unsafeApi$.pipeState(
|
||||
map((v) => (v === SUSPENSE ? null : (v as number))),
|
||||
withDefault(null),
|
||||
)
|
||||
const isIntegerStr = (str: string) => /^\d+$/.test(str)
|
||||
const nonce$ = state(
|
||||
mergeWithKey({
|
||||
nonceChanged$,
|
||||
nonceBlurred$,
|
||||
}).pipe(
|
||||
scan(
|
||||
(acc, v) =>
|
||||
v.type === "nonceChanged$" ? v.payload : isIntegerStr(acc) ? acc : "",
|
||||
"",
|
||||
),
|
||||
distinctUntilChanged(),
|
||||
),
|
||||
"",
|
||||
)
|
||||
|
||||
type Mortality = NonNullable<TxOptions<any, any>["mortality"]>
|
||||
const DEFAULT_MORTAL = {
|
||||
mortal: true,
|
||||
period: 64,
|
||||
}
|
||||
// powers of 2 from 4 to 16 (incl)
|
||||
const periodOptions = new Array(16 - 4 + 1).fill(0).map((_, i) => 1 << (i + 4))
|
||||
const [mortality$, setMortality] = createState<Mortality>(DEFAULT_MORTAL)
|
||||
const [tip$, setTip] = createState("0")
|
||||
|
||||
const transaction$ = state(
|
||||
combineLatest([unsafeApi$, callData$]).pipe(
|
||||
switchMapSuspended(([unsafeApi, callData]) =>
|
||||
callData ? unsafeApi.txFromCallData(callData) : [null],
|
||||
),
|
||||
liftSuspense(),
|
||||
map((v) => (v === SUSPENSE ? null : v)),
|
||||
),
|
||||
null,
|
||||
)
|
||||
|
||||
const txOptions$ = state(
|
||||
combineLatest([
|
||||
nonce$.pipe(map((v) => (isIntegerStr(v) ? Number(v) : null))),
|
||||
mortality$,
|
||||
tip$.pipe(map((v) => (isIntegerStr(v) ? BigInt(v) : null))),
|
||||
customSignedExtensions$,
|
||||
]).pipe(
|
||||
map(([nonce, mortality, tip, signedExt]): TxOptions<any, any> => {
|
||||
return {
|
||||
mortality,
|
||||
nonce: nonce ?? undefined,
|
||||
tip: tip ?? undefined,
|
||||
customSignedExtensions: signedExt,
|
||||
}
|
||||
}),
|
||||
),
|
||||
{} satisfies TxOptions<any, any>,
|
||||
)
|
||||
|
||||
export const paymentInfo$ = state(
|
||||
combineLatest([transaction$, selectedAccount$, txOptions$]).pipe(
|
||||
switchMapSuspended(([tx, account, txOptions]) => {
|
||||
if (!tx || !account) return [null]
|
||||
|
||||
// Adding a small delay for debouncing quick input changes
|
||||
return timer(200).pipe(
|
||||
switchMap(() =>
|
||||
tx.getPaymentInfo(getAccountPublicKey(account), txOptions),
|
||||
),
|
||||
catchError((ex) => {
|
||||
console.error(ex)
|
||||
return of(null)
|
||||
}),
|
||||
)
|
||||
}),
|
||||
liftSuspense(),
|
||||
map((v) => (v === SUSPENSE ? null : v)),
|
||||
),
|
||||
null,
|
||||
)
|
||||
const accountBalance$ = state(
|
||||
combineLatest([selectedAccount$, client$]).pipe(
|
||||
switchMapSuspended(([account, client]) =>
|
||||
account
|
||||
? client
|
||||
.getTypedApi(polkadot_people)
|
||||
.query.System.Account.getValue(getAccountGenericAddress(account))
|
||||
: [],
|
||||
),
|
||||
liftSuspense(),
|
||||
map((v) => (v === SUSPENSE ? null : v)),
|
||||
map((v) => {
|
||||
if (!v) return null
|
||||
const { reserved, free, frozen } = v.data
|
||||
const total = reserved + free
|
||||
|
||||
// TODO ED
|
||||
const untouchable = total == 0n ? 0n : maxBigInt(frozen - reserved, 0n)
|
||||
|
||||
return free - untouchable
|
||||
}),
|
||||
),
|
||||
null,
|
||||
)
|
||||
|
||||
export const SubmitExtrinsic = forwardRef<HTMLElement>((_, ref) => {
|
||||
const [account] = useSelectedAccount()
|
||||
@@ -208,8 +100,6 @@ export const SubmitExtrinsic = forwardRef<HTMLElement>((_, ref) => {
|
||||
const nonce = useStateObservable(nonce$)
|
||||
const mortality = useStateObservable(mortality$)
|
||||
const tip = useStateObservable(tip$)
|
||||
const paymentInfo = useStateObservable(paymentInfo$)
|
||||
const balance = useStateObservable(accountBalance$)
|
||||
const tx = useStateObservable(transaction$)
|
||||
const txOptions = useStateObservable(txOptions$)
|
||||
const [isSigning, setIsSigning] = useState(false)
|
||||
@@ -326,25 +216,11 @@ export const SubmitExtrinsic = forwardRef<HTMLElement>((_, ref) => {
|
||||
<CustomSignedExtDialog />
|
||||
</section>
|
||||
|
||||
<section className="mx-4 space-y-3 border-t border-border py-4">
|
||||
<h3 className="text-sm font-medium">Fees</h3>
|
||||
<FeeRow
|
||||
label="Estimated fee"
|
||||
value={
|
||||
paymentInfo ? (
|
||||
<TokenAmount>{paymentInfo.partial_fee}</TokenAmount>
|
||||
) : (
|
||||
"…"
|
||||
)
|
||||
}
|
||||
/>
|
||||
<FeeRow
|
||||
label="Account spendable balance"
|
||||
value={balance == null ? "…" : <TokenAmount>{balance}</TokenAmount>}
|
||||
/>
|
||||
</section>
|
||||
<Estimates />
|
||||
|
||||
<section className="mx-4 space-y-3 border-t border-border py-4">
|
||||
<DryRun />
|
||||
|
||||
<ActionButton
|
||||
className="flex w-full items-center justify-center gap-2 rounded-md py-2.5 text-sm font-semibold"
|
||||
disabled={!tx || !account?.signer || isSigning}
|
||||
@@ -471,11 +347,3 @@ const SubmitRow: FC<{
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
||||
const FeeRow: FC<{ label: string; value: ReactNode }> = ({ label, value }) => (
|
||||
<div className="flex items-center justify-between gap-3 py-1.5">
|
||||
<span className="text-sm text-muted-foreground">{label}</span>
|
||||
<span className="text-right font-mono text-sm">{value}</span>
|
||||
</div>
|
||||
)
|
||||
const maxBigInt = (a: bigint, b: bigint) => (a > b ? a : b)
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import { createState } from "@/lib/externalState"
|
||||
import { unsafeApi$ } from "@/state/chains/chain.state"
|
||||
import { liftSuspense, state, SUSPENSE } from "@react-rxjs/core"
|
||||
import {
|
||||
createSignal,
|
||||
mergeWithKey,
|
||||
switchMapSuspended,
|
||||
} from "@react-rxjs/utils"
|
||||
import { TxOptions } from "polkadot-api"
|
||||
import { combineLatest, distinctUntilChanged, map, scan } from "rxjs"
|
||||
import { callData$ } from "../componentValue.state"
|
||||
import { customSignedExtensions$ } from "../CustomSignedExt"
|
||||
|
||||
export const [nonceChanged$, setNonce] = createSignal<string>()
|
||||
export const [nonceBlurred$, blurNonce] = createSignal()
|
||||
|
||||
const isIntegerStr = (str: string) => /^\d+$/.test(str)
|
||||
export const nonce$ = state(
|
||||
mergeWithKey({
|
||||
nonceChanged$,
|
||||
nonceBlurred$,
|
||||
}).pipe(
|
||||
scan(
|
||||
(acc, v) =>
|
||||
v.type === "nonceChanged$" ? v.payload : isIntegerStr(acc) ? acc : "",
|
||||
"",
|
||||
),
|
||||
),
|
||||
"",
|
||||
)
|
||||
|
||||
type Mortality = NonNullable<TxOptions<any, any>["mortality"]>
|
||||
export const DEFAULT_MORTAL = {
|
||||
mortal: true,
|
||||
period: 64,
|
||||
}
|
||||
|
||||
export const [mortality$, setMortality] = createState<Mortality>(DEFAULT_MORTAL)
|
||||
export const [tip$, setTip] = createState("0")
|
||||
|
||||
export const transaction$ = state(
|
||||
combineLatest([unsafeApi$, callData$]).pipe(
|
||||
switchMapSuspended(([unsafeApi, callData]) =>
|
||||
callData ? unsafeApi.txFromCallData(callData) : [null],
|
||||
),
|
||||
liftSuspense(),
|
||||
map((v) => (v === SUSPENSE ? null : v)),
|
||||
),
|
||||
null,
|
||||
)
|
||||
|
||||
export const txOptions$ = state(
|
||||
combineLatest([
|
||||
nonce$.pipe(
|
||||
distinctUntilChanged(),
|
||||
map((v) => (isIntegerStr(v) ? Number(v) : null)),
|
||||
),
|
||||
mortality$,
|
||||
tip$.pipe(map((v) => (isIntegerStr(v) ? BigInt(v) : null))),
|
||||
customSignedExtensions$,
|
||||
]).pipe(
|
||||
map(([nonce, mortality, tip, signedExt]): TxOptions<any, any> => {
|
||||
return {
|
||||
mortality,
|
||||
nonce: nonce ?? undefined,
|
||||
tip: tip ?? undefined,
|
||||
customSignedExtensions: signedExt,
|
||||
}
|
||||
}),
|
||||
),
|
||||
{} satisfies TxOptions<any, any>,
|
||||
)
|
||||
@@ -0,0 +1,320 @@
|
||||
import { chainClient$ } from "@/state/chains/chain.state"
|
||||
import { selectedAccount$ } from "@/state/polkahub"
|
||||
import {
|
||||
DotAh,
|
||||
TransactionValidityTransactionSource,
|
||||
} from "@polkadot-api/descriptors"
|
||||
import { forklift, fromWorker } from "@polkadot-api/forklift"
|
||||
import Worker from "@polkadot-api/forklift/worker?worker"
|
||||
import { ChainHead$ } from "@polkadot-api/observable-client"
|
||||
import { shareLatest } from "@react-rxjs/core"
|
||||
import {
|
||||
AccountId,
|
||||
Binary,
|
||||
createClient,
|
||||
Enum,
|
||||
HexString,
|
||||
InvalidTxError,
|
||||
PolkadotClient,
|
||||
Transaction,
|
||||
} from "polkadot-api"
|
||||
import { getPolkadotSigner } from "polkadot-api/signer"
|
||||
import { AccountAddress } from "polkahub"
|
||||
import {
|
||||
catchError,
|
||||
combineLatest,
|
||||
filter,
|
||||
firstValueFrom,
|
||||
lastValueFrom,
|
||||
map,
|
||||
Observable,
|
||||
switchMap,
|
||||
take,
|
||||
TeardownLogic,
|
||||
toArray,
|
||||
} from "rxjs"
|
||||
|
||||
const promiseWithTeardown = <T>(
|
||||
deferFn: () => Promise<{
|
||||
value: T
|
||||
teardown: TeardownLogic
|
||||
}>,
|
||||
) =>
|
||||
new Observable<T>((obs) => {
|
||||
deferFn().then(
|
||||
({ value, teardown }) => {
|
||||
obs.add(teardown)
|
||||
obs.next(value)
|
||||
},
|
||||
(ex) => obs.error(ex),
|
||||
)
|
||||
})
|
||||
|
||||
const forkLift$ = chainClient$.pipe(
|
||||
switchMap(({ client, chainHead }) =>
|
||||
promiseWithTeardown(async () => {
|
||||
const [forklift, worker] = await createTmpForklift(client, chainHead)
|
||||
const forkClient = createClient(
|
||||
// withLogsRecorder(console.log, forklift.serve),
|
||||
forklift.serve,
|
||||
)
|
||||
|
||||
return {
|
||||
value: { forklift, forkClient },
|
||||
teardown: () => {
|
||||
forkClient.destroy()
|
||||
forklift.destroy()
|
||||
worker.terminate()
|
||||
},
|
||||
}
|
||||
}),
|
||||
),
|
||||
shareLatest(),
|
||||
)
|
||||
|
||||
const fakeSign$ = (tx: Transaction, txOptions: any) =>
|
||||
combineLatest({
|
||||
signer: selectedAccount$.pipe(
|
||||
map((account) => (account ? createFakeSigner(account.address) : null)),
|
||||
),
|
||||
mockChain: forkLift$.pipe(
|
||||
switchMap(async ({ forkClient }) => {
|
||||
const unsafeApi = forkClient.getUnsafeApi<DotAh>()
|
||||
return {
|
||||
client: forkClient,
|
||||
unsafeApi,
|
||||
tx: await unsafeApi.txFromCallData(await tx.getEncodedData()),
|
||||
}
|
||||
}),
|
||||
),
|
||||
}).pipe(
|
||||
switchMap(async ({ signer, mockChain: { tx, unsafeApi, client } }) => {
|
||||
if (!signer) return null
|
||||
|
||||
const extrinsic = await tx.sign(signer, txOptions)
|
||||
|
||||
return { extrinsic, tx, unsafeApi, client }
|
||||
}),
|
||||
)
|
||||
|
||||
export const validate$ = (tx: Transaction, txOptions: any) =>
|
||||
fakeSign$(tx, txOptions).pipe(
|
||||
switchMap(async (evt) =>
|
||||
evt
|
||||
? evt.unsafeApi.apis.TaggedTransactionQueue.validate_transaction(
|
||||
TransactionValidityTransactionSource.External(),
|
||||
evt.extrinsic.slice(2),
|
||||
(await evt.client.getFinalizedBlock()).hash,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
map((evt) =>
|
||||
!evt
|
||||
? {
|
||||
type: "no-signer" as const,
|
||||
value: undefined,
|
||||
}
|
||||
: evt.success
|
||||
? {
|
||||
type: "valid" as const,
|
||||
value: undefined,
|
||||
}
|
||||
: {
|
||||
type: "invalid" as const,
|
||||
value: evt.value.value.type,
|
||||
},
|
||||
),
|
||||
catchError((ex) => {
|
||||
console.error(ex)
|
||||
return [
|
||||
{
|
||||
type: "error" as const,
|
||||
value: ex.error,
|
||||
},
|
||||
]
|
||||
}),
|
||||
take(1),
|
||||
)
|
||||
|
||||
export const dryRun$ = (tx: Transaction, txOptions: any) =>
|
||||
fakeSign$(tx, txOptions).pipe(
|
||||
switchMap((evt) =>
|
||||
evt ? evt.client.submitAndWatch(evt.extrinsic) : [null],
|
||||
),
|
||||
map((evt) => {
|
||||
if (!evt) {
|
||||
return {
|
||||
type: "no-signer" as const,
|
||||
value: undefined,
|
||||
}
|
||||
}
|
||||
if (evt.type === "txBestBlocksState" && evt.found) {
|
||||
return {
|
||||
type: "valid" as const,
|
||||
value: {
|
||||
ok: evt.ok,
|
||||
dispatchError: evt.dispatchError,
|
||||
events: evt.events,
|
||||
},
|
||||
}
|
||||
}
|
||||
return null
|
||||
}),
|
||||
catchError((ex) => {
|
||||
if (ex instanceof InvalidTxError) {
|
||||
return [
|
||||
{
|
||||
type: "invalid" as const,
|
||||
value: ex.error,
|
||||
},
|
||||
]
|
||||
}
|
||||
console.error(ex)
|
||||
return [
|
||||
{
|
||||
type: "error" as const,
|
||||
value: ex.error,
|
||||
},
|
||||
]
|
||||
}),
|
||||
filter((v) => v !== null),
|
||||
take(1),
|
||||
)
|
||||
|
||||
const codeCache = new WeakMap<Uint8Array, Promise<Uint8Array>>()
|
||||
const CODE_KEY = "0x3a636f6465"
|
||||
const PARAMETERS_KEY =
|
||||
"0xc63bdd4a39095ccf55623a6f2872bf8ac63bdd4a39095ccf55623a6f2872bf8a"
|
||||
|
||||
const createTmpForklift = async (
|
||||
client: PolkadotClient,
|
||||
chainHead: ChainHead$,
|
||||
) => {
|
||||
const [block] = await client.getBestBlocks()
|
||||
const unhodl = client.hodlBlock(block.hash)
|
||||
const metadata = await client.getMetadata(block.hash)
|
||||
|
||||
// forklift needs the code, which is a big-ass query (~4MB).
|
||||
// PAPI doesn't have it, but we should prevent this query to be repeated by every block when the runtime is the same
|
||||
if (!codeCache.has(metadata)) {
|
||||
const codeP = firstValueFrom(
|
||||
chainHead
|
||||
.storage$(block.hash, "value", () => CODE_KEY)
|
||||
.pipe(
|
||||
map((v) => {
|
||||
if (!v.value) {
|
||||
throw new Error("Code not available")
|
||||
}
|
||||
return Binary.fromHex(v.value)
|
||||
}),
|
||||
),
|
||||
)
|
||||
codeCache.set(metadata, codeP)
|
||||
}
|
||||
|
||||
// We can also optimise by pre-quering "Parameters.Parameters", which is often serialised and is mostly empty
|
||||
const parametersP = firstValueFrom(
|
||||
chainHead
|
||||
.storage$(block.hash, "descendantsValues", () => PARAMETERS_KEY)
|
||||
.pipe(
|
||||
map((v) =>
|
||||
Object.fromEntries(
|
||||
v.value.map(({ key, value }) => [key, Binary.fromHex(value)]),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
const [code, parameters] = await Promise.all([
|
||||
codeCache.get(metadata)!,
|
||||
parametersP,
|
||||
])
|
||||
|
||||
const getBlock = async () => ({
|
||||
blockHash: block.hash,
|
||||
header: await client.getBlockHeader(block.hash),
|
||||
body: await client.getBlockBody(block.hash),
|
||||
})
|
||||
const getStorage = async (key: HexString) => {
|
||||
if (key === CODE_KEY) return code
|
||||
if (key.startsWith(PARAMETERS_KEY)) return parameters[key] ?? null
|
||||
|
||||
return firstValueFrom(
|
||||
chainHead
|
||||
.storage$(block.hash, "value", () => key)
|
||||
.pipe(map((v) => (v.value ? Binary.fromHex(v.value) : null))),
|
||||
)
|
||||
}
|
||||
const getStorageBatch = async (keys: HexString[]) => {
|
||||
if (!keys.length) return []
|
||||
|
||||
const result = new Array(keys.length)
|
||||
const keyToIdx = Object.fromEntries(keys.map((key, i) => [key, i]))
|
||||
|
||||
const results = await lastValueFrom(
|
||||
chainHead
|
||||
.storageQueries$(
|
||||
block.hash,
|
||||
keys.map((key) => ({
|
||||
type: "value",
|
||||
key,
|
||||
})),
|
||||
)
|
||||
.pipe(toArray()),
|
||||
)
|
||||
results.forEach(
|
||||
(r) =>
|
||||
(result[keyToIdx[r.key]] = r.value ? Binary.fromHex(r.value) : null),
|
||||
)
|
||||
|
||||
return result
|
||||
}
|
||||
const getStorageDescendants = (prefix: HexString) => {
|
||||
return firstValueFrom(
|
||||
chainHead
|
||||
.storage$(block.hash, "descendantsValues", () => prefix)
|
||||
.pipe(
|
||||
map((v) =>
|
||||
Object.fromEntries(
|
||||
v.value.map(({ key, value }) => [key, Binary.fromHex(value)]),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
const getChainSpecData = client.getChainSpecData
|
||||
|
||||
const forkliftWorker = new Worker()
|
||||
return [
|
||||
forklift(
|
||||
{
|
||||
block: getBlock(),
|
||||
getStorage,
|
||||
getStorageBatch,
|
||||
getStorageDescendants,
|
||||
getChainSpecData,
|
||||
destroy() {
|
||||
unhodl()
|
||||
},
|
||||
},
|
||||
{
|
||||
mockSignatureHost: true,
|
||||
disableOnIdle: true,
|
||||
buildBlockMode: Enum("timer", 0),
|
||||
executor: fromWorker(forkliftWorker),
|
||||
},
|
||||
),
|
||||
forkliftWorker,
|
||||
] as const
|
||||
}
|
||||
|
||||
const decodeAddress = (address: AccountAddress) =>
|
||||
address.startsWith("0x") ? Binary.fromHex(address) : AccountId().enc(address)!
|
||||
|
||||
export const createFakeSigner = (address: AccountAddress) =>
|
||||
getPolkadotSigner(decodeAddress(address), "Sr25519", () => {
|
||||
// From https://wiki.acala.network/build/sdks/homa
|
||||
const signature = new Uint8Array(64)
|
||||
signature.fill(0xcd)
|
||||
signature.set([0xde, 0xad, 0xbe, 0xef])
|
||||
return signature
|
||||
})
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createMetadataEntryState } from "@/components/MetadataEntryInput"
|
||||
import { pushWorkspaceEntry, WorkspaceEntryData } from "@/components/Workspace"
|
||||
import { getHashParams } from "@/hashParams"
|
||||
import { runtimeCtxAt$, unsafeApi$ } from "@/state/chains/chain.state"
|
||||
import { genericUnsafeApi$, runtimeCtxAt$ } from "@/state/chains/chain.state"
|
||||
import { RuntimeContext } from "@polkadot-api/observable-client"
|
||||
import { state } from "@react-rxjs/core"
|
||||
import { ServerCog } from "lucide-react"
|
||||
@@ -108,7 +108,7 @@ export const runtimeCallToWorkspaceEntry = async (
|
||||
query: RuntimeCallQuery,
|
||||
): Promise<WorkspaceEntryData<RuntimeCallWorkspaceContext>> => {
|
||||
const [unsafeApi, ctx] = await firstValueFrom(
|
||||
combineLatest([unsafeApi$, runtimeCtxAt$(query.blockHash)]),
|
||||
combineLatest([genericUnsafeApi$, runtimeCtxAt$(query.blockHash)]),
|
||||
)
|
||||
|
||||
const query$ = from(
|
||||
|
||||
@@ -5,10 +5,10 @@ import { getHashParams } from "@/hashParams"
|
||||
import {
|
||||
chainClient$,
|
||||
client$,
|
||||
genericUnsafeApi$,
|
||||
runtimeCtx$,
|
||||
runtimeCtxAt$,
|
||||
selectedChainChanged$,
|
||||
unsafeApi$,
|
||||
} from "@/state/chains/chain.state"
|
||||
import {
|
||||
BlockInfo,
|
||||
@@ -180,7 +180,7 @@ export const storageSubscriptionToWorkspaceEntry = async ({
|
||||
const [ctx, unsafeApi] = await firstValueFrom(
|
||||
combineLatest([
|
||||
blockHash ? runtimeCtxAt$(blockHash) : runtimeCtx$,
|
||||
unsafeApi$,
|
||||
genericUnsafeApi$,
|
||||
]),
|
||||
)
|
||||
const entry = getEntry(ctx, getStorageItem(ctx, pallet, item)!.item.type)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createMetadataEntryState } from "@/components/MetadataEntryInput"
|
||||
import { pushWorkspaceEntry, WorkspaceEntryData } from "@/components/Workspace"
|
||||
import { getHashParams } from "@/hashParams"
|
||||
import { runtimeCtxAt$, unsafeApi$ } from "@/state/chains/chain.state"
|
||||
import { genericUnsafeApi$, runtimeCtxAt$ } from "@/state/chains/chain.state"
|
||||
import { RuntimeContext } from "@polkadot-api/observable-client"
|
||||
import { shareLatest, state } from "@react-rxjs/core"
|
||||
import { SquareFunction } from "lucide-react"
|
||||
@@ -110,7 +110,7 @@ export const viewFnCallToWorkspaceEntry = async (
|
||||
call: ViewFnCall,
|
||||
): Promise<WorkspaceEntryData<ViewFnWorkspaceContext>> => {
|
||||
const [unsafeApi, ctx] = await firstValueFrom(
|
||||
combineLatest([unsafeApi$, runtimeCtxAt$(call.blockHash)]),
|
||||
combineLatest([genericUnsafeApi$, runtimeCtxAt$(call.blockHash)]),
|
||||
)
|
||||
|
||||
const query$ = from(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createChopsticksProvider } from "@/chopsticks/chopsticks"
|
||||
import { getHashParams, setHashParams } from "@/hashParams"
|
||||
import { DotAh } from "@polkadot-api/descriptors"
|
||||
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders"
|
||||
import type {
|
||||
ChainHead$,
|
||||
@@ -10,10 +11,16 @@ import {
|
||||
HexString,
|
||||
unifyMetadata,
|
||||
} from "@polkadot-api/substrate-bindings"
|
||||
import { liftSuspense, sinkSuspense, state, SUSPENSE } from "@react-rxjs/core"
|
||||
import {
|
||||
liftSuspense,
|
||||
sinkSuspense,
|
||||
state,
|
||||
StateObservable,
|
||||
SUSPENSE,
|
||||
} from "@react-rxjs/core"
|
||||
import { createSignal } from "@react-rxjs/utils"
|
||||
import { get, update } from "idb-keyval"
|
||||
import { createClient } from "polkadot-api"
|
||||
import { ChainDefinition, createClient, TypedApi } from "polkadot-api"
|
||||
import { withLogsRecorder } from "polkadot-api/logs-provider"
|
||||
import { fromHex, toHex } from "polkadot-api/utils"
|
||||
import {
|
||||
@@ -249,8 +256,11 @@ export const canSetStorage$ = state(
|
||||
)
|
||||
|
||||
export const unsafeApi$ = chainClient$.pipeState(
|
||||
map(({ client }) => client.getUnsafeApi()),
|
||||
map(({ client }) => client.getUnsafeApi<DotAh>()),
|
||||
)
|
||||
export const genericUnsafeApi$ = unsafeApi$ as StateObservable<
|
||||
TypedApi<ChainDefinition, false>
|
||||
>
|
||||
|
||||
const uncachedRuntimeCtx$ = chainClient$.pipeState(
|
||||
switchMap(({ chainHead }) => chainHead.runtime$),
|
||||
|
||||
Reference in New Issue
Block a user