diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 99cf8ee90..a27d6e290 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -258,3 +258,18 @@ jobs:
- run: cd scripts/mesh-cli && npm publish --access public
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
+
+ publish-meshsdk-midnight-setup:
+ needs: [build, check-version]
+ if: needs.check-version.outputs.version-updated == 'true'
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ registry-url: https://registry.npmjs.org/
+ - run: npm install && npm run build
+ - run: cd packages/midnight-setup && npm publish --access public
+ env:
+ NODE_AUTH_TOKEN: ${{secrets.npm_token}}
diff --git a/package-lock.json b/package-lock.json
index 1fda67a4c..bffcd3c8c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -643,6 +643,49 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@apollo/client": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.14.0.tgz",
+ "integrity": "sha512-0YQKKRIxiMlIou+SekQqdCo0ZTHxOcES+K8vKB53cIDpwABNR0P0yRzPgsbgcj3zRJniD93S/ontsnZsCLZrxQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@graphql-typed-document-node/core": "^3.1.1",
+ "@wry/caches": "^1.0.0",
+ "@wry/equality": "^0.5.6",
+ "@wry/trie": "^0.5.0",
+ "graphql-tag": "^2.12.6",
+ "hoist-non-react-statics": "^3.3.2",
+ "optimism": "^0.18.0",
+ "prop-types": "^15.7.2",
+ "rehackt": "^0.1.0",
+ "symbol-observable": "^4.0.0",
+ "ts-invariant": "^0.10.3",
+ "tslib": "^2.3.0",
+ "zen-observable-ts": "^1.2.5"
+ },
+ "peerDependencies": {
+ "graphql": "^15.0.0 || ^16.0.0",
+ "graphql-ws": "^5.5.5 || ^6.0.3",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc",
+ "subscriptions-transport-ws": "^0.9.0 || ^0.11.0"
+ },
+ "peerDependenciesMeta": {
+ "graphql-ws": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "subscriptions-transport-ws": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
@@ -1290,21 +1333,6 @@
"node": ">=14"
}
},
- "node_modules/@cardano-ogmios/client/node_modules/utf-8-validate": {
- "version": "5.0.10",
- "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
- "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "node-gyp-build": "^4.3.0"
- },
- "engines": {
- "node": ">=6.14.2"
- }
- },
"node_modules/@cardano-ogmios/client/node_modules/ws": {
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
@@ -11034,6 +11062,19 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
+ "node_modules/@dao-xyz/borsh": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/@dao-xyz/borsh/-/borsh-5.2.4.tgz",
+ "integrity": "sha512-HKjOMXBQvr2riUIX/g+sLOmgDsk16zuMa0VZKMfj0XLp3MlafMxkwuBJyJk0apqUpKxywXeitgFHGFOGNkn+Kw==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/benchmark": "^2.1.5",
+ "protobufjs": "^7.5.4"
+ }
+ },
"node_modules/@emnapi/core": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz",
@@ -11676,6 +11717,16 @@
"integrity": "sha512-DjIZsnL3CyP/yQ/vUYA9cjrD0a/8YXejI5ZmsaOiT16cLfZcTwaCxIN01/ys4jsy+dZCQ/9DnWFn7AEFbiMDaA==",
"license": "MIT"
},
+ "node_modules/@graphql-typed-document-node/core": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz",
+ "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==",
+ "license": "MIT",
+ "peer": true,
+ "peerDependencies": {
+ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
+ }
+ },
"node_modules/@harmoniclabs/bigint-utils": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@harmoniclabs/bigint-utils/-/bigint-utils-1.0.0.tgz",
@@ -12610,6 +12661,10 @@
"resolved": "packages/mesh-hydra",
"link": true
},
+ "node_modules/@meshsdk/midnight-setup": {
+ "resolved": "packages/midnight-setup",
+ "link": true
+ },
"node_modules/@meshsdk/provider": {
"resolved": "packages/mesh-provider",
"link": true
@@ -12907,6 +12962,347 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/@midnight-ntwrk/compact-runtime": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/compact-runtime/-/compact-runtime-0.8.1.tgz",
+ "integrity": "sha512-ZXG/iprEqTCxQC/P1oETGOR5CnsoemPsfb17eSANPRsm+11AcIOP0Tp8KJipN+GbycgxOA+fAVwLFqA1hDCgbw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@midnight-ntwrk/onchain-runtime": "^0.3.0",
+ "@types/object-inspect": "^1.8.1",
+ "object-inspect": "^1.12.3"
+ }
+ },
+ "node_modules/@midnight-ntwrk/dapp-connector-api": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/dapp-connector-api/-/dapp-connector-api-3.0.0.tgz",
+ "integrity": "sha512-A/AhsNjibrOSaUiPhQhxANeW9178uYnzeBFBf30YCvyvWg0YWCbhQfc7dRpiL7iBoX3Sxt9mtf+Svx4ZygLajg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@midnight-ntwrk/wallet-api": "^5.0.0",
+ "@midnight-ntwrk/zswap": "^4.0.0",
+ "ts-custom-error": "^3.3.1"
+ }
+ },
+ "node_modules/@midnight-ntwrk/ledger": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/ledger/-/ledger-4.0.0.tgz",
+ "integrity": "sha512-cnJisY8uQ4NO54miDnjs/ov6n102ZPfKEPxtiDKVEdlKijcc70jz/CI2yBCc0itlwwaqma7FM2Ou5N4pWpbwbg=="
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-contracts": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/midnight-js-contracts/-/midnight-js-contracts-2.0.2.tgz",
+ "integrity": "sha512-L1MPw5cmMq4bA5MQrnq9SWMl2wfmwOS2oK+lLwvtiYGtvd1/JrIXxBZk1759Sf9xTtVxmMdDS4yFLd3US0en2A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@midnight-ntwrk/midnight-js-network-id": "2.0.2",
+ "@midnight-ntwrk/midnight-js-types": "2.0.2",
+ "@midnight-ntwrk/midnight-js-utils": "2.0.2"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-fetch-zk-config-provider": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/midnight-js-fetch-zk-config-provider/-/midnight-js-fetch-zk-config-provider-2.0.2.tgz",
+ "integrity": "sha512-+7zrFkKh6AsxRHXeD0o4Nnhv/SCAnIadwoG+pT1XfD0knaMLu7rjHM/yFtwj6168dJF+McaPdkWaa+TGipRHtQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@midnight-ntwrk/midnight-js-types": "2.0.2",
+ "cross-fetch": "^4.0.0"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-fetch-zk-config-provider/node_modules/cross-fetch": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz",
+ "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "node-fetch": "^2.7.0"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-fetch-zk-config-provider/node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-http-client-proof-provider": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/midnight-js-http-client-proof-provider/-/midnight-js-http-client-proof-provider-2.0.2.tgz",
+ "integrity": "sha512-zhSZA2zjo+ynzan28JJePReMhyLBVaRgf7hEUj1thVG/1bRuYWDQv/cMqr+x/ZocCDTqbbWdb/6gpHOkO9aWXg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@dao-xyz/borsh": "^5.1.5",
+ "@midnight-ntwrk/midnight-js-network-id": "2.0.2",
+ "@midnight-ntwrk/midnight-js-types": "2.0.2",
+ "cross-fetch": "^4.0.0",
+ "fetch-retry": "^6.0.0",
+ "lodash": "^4.17.21"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-http-client-proof-provider/node_modules/cross-fetch": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz",
+ "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "node-fetch": "^2.7.0"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-http-client-proof-provider/node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-indexer-public-data-provider": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/midnight-js-indexer-public-data-provider/-/midnight-js-indexer-public-data-provider-2.0.2.tgz",
+ "integrity": "sha512-yn2EriaclSNUwZqZNsgJv//6vPkW2NrA84e9S6zs7KEDDoCobtiFBlOHR54IXM2fNs3DnAojsVZiQaTY0Lq4vQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@apollo/client": "^3.13.8",
+ "@midnight-ntwrk/midnight-js-network-id": "2.0.2",
+ "@midnight-ntwrk/midnight-js-types": "2.0.2",
+ "buffer": "^6.0.3",
+ "cross-fetch": "^4.0.0",
+ "graphql": "^16.8.0",
+ "graphql-ws": "^6.0.0",
+ "isomorphic-ws": "^5.0.0",
+ "rxjs": "^7.5.0",
+ "ws": "^8.14.2",
+ "zen-observable-ts": "^1.1.0"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-indexer-public-data-provider/node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-indexer-public-data-provider/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-indexer-public-data-provider/node_modules/cross-fetch": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz",
+ "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "node-fetch": "^2.7.0"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-indexer-public-data-provider/node_modules/isomorphic-ws": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz",
+ "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==",
+ "license": "MIT",
+ "peer": true,
+ "peerDependencies": {
+ "ws": "*"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-indexer-public-data-provider/node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-level-private-state-provider": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/midnight-js-level-private-state-provider/-/midnight-js-level-private-state-provider-2.0.2.tgz",
+ "integrity": "sha512-lI/E5Fs4gVJ9LN4DEYbrssoz2YdWgfiIl6ZpQsc4o7QUCGAzKaK5hAPiQ5dgeL3G2eFbLWVxwpJFq9O5/oJyAg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@midnight-ntwrk/midnight-js-types": "2.0.2",
+ "abstract-level": "^2.0.0",
+ "buffer": "^6.0.3",
+ "fp-ts": "^2.16.1",
+ "io-ts": "^2.2.20",
+ "level": "^9.0.0",
+ "lodash": "^4.17.21",
+ "superjson": "^2.0.0"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-level-private-state-provider/node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-level-private-state-provider/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-network-id": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/midnight-js-network-id/-/midnight-js-network-id-2.0.2.tgz",
+ "integrity": "sha512-ogBBC5Ox2B2QZo4XxXYr3AxwgUeC4LEmLasLInjMk0p0m//8iI6NmH4/5f0pEOxDtGSuA+piuSonxuQMLM6GUg==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/midnight-js-types/-/midnight-js-types-2.0.2.tgz",
+ "integrity": "sha512-ewHBQRCvY8u0+JAGdjQ86KsyoTA3dbNBLkuZ1o5U6vU/1jFjnFA1FL9skTgdXzSKjjfwA930i+OvbaUaUzFEHQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "rxjs": "^7.5.0"
+ }
+ },
+ "node_modules/@midnight-ntwrk/midnight-js-utils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/midnight-js-utils/-/midnight-js-utils-2.0.2.tgz",
+ "integrity": "sha512-c01Nh9BfwxwijItgrieeXtdwfOZuQd9gWMX+294rT8Pq+vydIt61+0V89TLIT7nh/1d7Z2Bu9X5+9rFzfzwylA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@midnight-ntwrk/onchain-runtime": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/onchain-runtime/-/onchain-runtime-0.3.0.tgz",
+ "integrity": "sha512-vZWPoz7MhXO5UgWZET50g7APOcT5dbAfADDcrSreeOagV8lj7JJzlnYIIhrcUaMOv+NHWxPaUcJUYUkmu9LoTA=="
+ },
+ "node_modules/@midnight-ntwrk/wallet-api": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/wallet-api/-/wallet-api-5.0.0.tgz",
+ "integrity": "sha512-L5Z9+v+ouqTtPLoXpngtBVHZ0SmC3zLrCZbuYnd/ul6p9UbwUQ3AQeqMhclv2jhwFRNYsL0fBOqpD5dvs4SvLQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@midnight-ntwrk/zswap": "^4.0.0"
+ },
+ "peerDependencies": {
+ "rxjs": "7.x"
+ }
+ },
+ "node_modules/@midnight-ntwrk/zswap": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@midnight-ntwrk/zswap/-/zswap-4.0.0.tgz",
+ "integrity": "sha512-yKfzp4M/wUkqxUJv1D2SizojYdWYnF3FDeKaxPehLPOFC4BrR9KnLZsNR2Y/occ8a4yFDtQXf7bN1QvK5k7Grw=="
+ },
"node_modules/@multiformats/dns": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@multiformats/dns/-/dns-1.0.9.tgz",
@@ -13455,6 +13851,80 @@
"source-map-support": "^0.5.16"
}
},
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
"node_modules/@radix-ui/primitive": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
@@ -13880,6 +14350,30 @@
}
}
},
+ "node_modules/@radix-ui/react-progress": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz",
+ "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-roving-focus": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz",
@@ -15613,6 +16107,13 @@
"@types/node": "*"
}
},
+ "node_modules/@types/benchmark": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@types/benchmark/-/benchmark-2.1.5.tgz",
+ "integrity": "sha512-cKio2eFB3v7qmKcvIHLUMw/dIx/8bhWPuzpzRT4unCPRTD8VdA9Zb0afxpcxOqR4PixRS7yT42FqGS8BYL8g1w==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/@types/blake2b": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@types/blake2b/-/blake2b-2.1.3.tgz",
@@ -15822,6 +16323,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/object-inspect": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/@types/object-inspect/-/object-inspect-1.13.0.tgz",
+ "integrity": "sha512-lwGTVESDDV+XsQ1pH4UifpJ1f7OtXzQ6QBOX2Afq2bM/T3oOt8hF6exJMjjIjtEWeAN2YAo25J7HxWh97CCz9w==",
+ "license": "MIT"
+ },
"node_modules/@types/prompts": {
"version": "2.4.9",
"resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.9.tgz",
@@ -16574,6 +17081,58 @@
"http-parser-js": "^0.4.3"
}
},
+ "node_modules/@wry/caches": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@wry/caches/-/caches-1.0.1.tgz",
+ "integrity": "sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@wry/context": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.4.tgz",
+ "integrity": "sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@wry/equality": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.7.tgz",
+ "integrity": "sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@wry/trie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.5.0.tgz",
+ "integrity": "sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@yarnpkg/lockfile": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
@@ -16606,6 +17165,70 @@
"integrity": "sha512-fxqCblJiIPdSXIUrxI0PL+eJG49QdP9SQ70qtB65MVAoMr2rASlOyAbJFOylfB467F/f+5BCLJJq58RYi7mGfg==",
"license": "Apache-2.0 OR MIT"
},
+ "node_modules/abstract-level": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-2.0.2.tgz",
+ "integrity": "sha512-pPJixmXk/kTKLB2sSue7o4Uj6TlLD2XfaP2gWZomHVCC6cuUGX/VslQqKG1yZHfXwBb/3lS6oSTMPGzh1P1iig==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "buffer": "^6.0.3",
+ "is-buffer": "^2.0.5",
+ "level-supports": "^6.0.0",
+ "level-transcoder": "^1.0.1",
+ "maybe-combine-errors": "^1.0.0",
+ "module-error": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/abstract-level/node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/abstract-level/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
"node_modules/acorn": {
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
@@ -17064,6 +17687,15 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/atomic-sleep": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
+ "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/autoprefixer": {
"version": "10.4.21",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
@@ -17941,6 +18573,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/browser-level": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-2.0.0.tgz",
+ "integrity": "sha512-RuYSCHG/jwFCrK+KWA3dLSUNLKHEgIYhO5ORPjJMjCt7T3e+RzpIDmYKWRHxq2pfKGXjlRuEff7y7RESAAgzew==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "abstract-level": "^2.0.1"
+ }
+ },
"node_modules/browser-resolve": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz",
@@ -18758,6 +19400,7 @@
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -18802,6 +19445,23 @@
"url": "https://polar.sh/cva"
}
},
+ "node_modules/classic-level": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-2.0.0.tgz",
+ "integrity": "sha512-ftiMvKgCQK+OppXcvMieDoYlYLYWhScK6yZRFBrrlHQRbm4k6Gr+yDgu/wt3V0k1/jtNbuiXAsRmuAFcD0Tx5Q==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "abstract-level": "^2.0.0",
+ "module-error": "^1.0.1",
+ "napi-macros": "^2.2.2",
+ "node-gyp-build": "^4.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/classnames": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
@@ -19090,6 +19750,22 @@
"node": ">= 0.6"
}
},
+ "node_modules/copy-anything": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
+ "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "is-what": "^4.1.8"
+ },
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
"node_modules/copy-to-clipboard": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
@@ -21475,7 +22151,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.x"
@@ -21635,6 +22310,15 @@
"integrity": "sha512-8Sld+DuyWRIftl86ZguJxR2oXCBccOiJxrY/Rj9/7ZBynW8pYMWzIcqxFL1da+25jaWJZVa+HHX/8SsA21JdTA==",
"license": "MIT"
},
+ "node_modules/fast-redact": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz",
+ "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/fastq": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
@@ -21677,6 +22361,13 @@
"node": "^12.20 || >= 14.13"
}
},
+ "node_modules/fetch-retry": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-6.0.0.tgz",
+ "integrity": "sha512-BUFj1aMubgib37I3v4q78fYo63Po7t4HUPTpQ6/QE6yK6cIQrP+W43FYToeTEyg5m2Y7eFUtijUuAv/PDlWuag==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/fflate": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
@@ -22066,6 +22757,12 @@
"node": ">=12.20.0"
}
},
+ "node_modules/fp-ts": {
+ "version": "2.16.11",
+ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.16.11.tgz",
+ "integrity": "sha512-LaI+KaX2NFkfn1ZGHoKCmcfv7yrZsC3b8NtWsTVQeHkq4F27vI5igUuO53sxqDEa2gNQMHFPmpojDw/1zmUK7w==",
+ "license": "MIT"
+ },
"node_modules/fraction.js": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
@@ -22653,6 +23350,63 @@
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"license": "MIT"
},
+ "node_modules/graphql": {
+ "version": "16.11.0",
+ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz",
+ "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
+ }
+ },
+ "node_modules/graphql-tag": {
+ "version": "2.12.6",
+ "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz",
+ "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
+ }
+ },
+ "node_modules/graphql-ws": {
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-6.0.6.tgz",
+ "integrity": "sha512-zgfER9s+ftkGKUZgc0xbx8T7/HMO4AV5/YuYiFc+AtgcO5T0v8AxYYNQ+ltzuzDZgNkYJaFspm5MMYLjQzrkmw==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=20"
+ },
+ "peerDependencies": {
+ "@fastify/websocket": "^10 || ^11",
+ "crossws": "~0.3",
+ "graphql": "^15.10.1 || ^16",
+ "uWebSockets.js": "^20",
+ "ws": "^8"
+ },
+ "peerDependenciesMeta": {
+ "@fastify/websocket": {
+ "optional": true
+ },
+ "crossws": {
+ "optional": true
+ },
+ "uWebSockets.js": {
+ "optional": true
+ },
+ "ws": {
+ "optional": true
+ }
+ }
+ },
"node_modules/handlebars": {
"version": "4.7.8",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
@@ -22987,10 +23741,28 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/hoist-non-react-statics/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true,
"license": "ISC"
},
"node_modules/html-escaper": {
@@ -23251,6 +24023,16 @@
"node": ">= 0.4"
}
},
+ "node_modules/io-ts": {
+ "version": "2.2.22",
+ "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-2.2.22.tgz",
+ "integrity": "sha512-FHCCztTkHoV9mdBsHpocLpdTAfh956ZQcIkWQxxS0U5HT53vtrcuYdQneEJKH6xILaLNzXVl2Cvwtoy8XNN0AA==",
+ "license": "MIT",
+ "peer": true,
+ "peerDependencies": {
+ "fp-ts": "^2.5.0"
+ }
+ },
"node_modules/ip": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz",
@@ -23410,6 +24192,30 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-buffer": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/is-builtin-module": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
@@ -23871,6 +24677,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-what": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
+ "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
"node_modules/is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
@@ -24822,6 +25641,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
"license": "MIT"
},
"node_modules/json-schema-traverse": {
@@ -25018,6 +25838,95 @@
"integrity": "sha512-t+KLJFkHPQk8lfN6WBOiGkiUXoub+gnb2XTYI2P3aiISL+94xgZ1vgz1SXN/N4hthuOoLXarXfBZPUruyjQtfA==",
"license": "MIT"
},
+ "node_modules/level": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/level/-/level-9.0.0.tgz",
+ "integrity": "sha512-n+mVuf63mUEkd8NUx7gwxY+QF5vtkibv6fXTGUgtHWLPDaA5/XZjLcI/Q1nQ8k6OttHT6Ezt+7nSEXsRUfHtOQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "abstract-level": "^2.0.1",
+ "browser-level": "^2.0.0",
+ "classic-level": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/level"
+ }
+ },
+ "node_modules/level-supports": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-6.2.0.tgz",
+ "integrity": "sha512-QNxVXP0IRnBmMsJIh+sb2kwNCYcKciQZJEt+L1hPCHrKNELllXhvrlClVHXBYZVT+a7aTSM6StgNXdAldoab3w==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/level-transcoder": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz",
+ "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "buffer": "^6.0.3",
+ "module-error": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/level-transcoder/node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/level-transcoder/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
"node_modules/leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -25219,6 +26128,13 @@
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==",
"license": "MIT"
},
+ "node_modules/long": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
+ "license": "Apache-2.0",
+ "peer": true
+ },
"node_modules/longest-streak": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
@@ -25301,6 +26217,15 @@
"node": ">=12.20.0"
}
},
+ "node_modules/lucide-react": {
+ "version": "0.523.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.523.0.tgz",
+ "integrity": "sha512-rUjQoy7egZT9XYVXBK1je9ckBnNp7qzRZOhLQx5RcEp2dCGlXo+mv6vf7Am4LimEcFBJIIZzSGfgTqc9QCrPSw==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/lunr": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
@@ -25430,6 +26355,16 @@
"node": ">= 0.4"
}
},
+ "node_modules/maybe-combine-errors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/maybe-combine-errors/-/maybe-combine-errors-1.0.0.tgz",
+ "integrity": "sha512-eefp6IduNPT6fVdwPp+1NgD0PML1NU5P6j1Mj5nz1nidX8/sWY7119WL8vTAHgqfsY74TzW0w1XPgdYEKkGZ5A==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -26457,6 +27392,7 @@
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
"integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
+ "dev": true,
"license": "ISC",
"engines": {
"node": ">=8"
@@ -26517,6 +27453,16 @@
"ufo": "^1.6.1"
}
},
+ "node_modules/module-error": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz",
+ "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/mri": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
@@ -26601,8 +27547,7 @@
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz",
"integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==",
- "license": "MIT",
- "optional": true
+ "license": "MIT"
},
"node_modules/napi-postinstall": {
"version": "0.3.4",
@@ -26818,7 +27763,6 @@
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
"integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
"license": "MIT",
- "optional": true,
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
@@ -26910,6 +27854,7 @@
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"hosted-git-info": "^2.1.4",
@@ -26922,6 +27867,7 @@
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver"
@@ -29644,6 +30590,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/on-exit-leak-free": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz",
+ "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -29698,6 +30653,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/optimism": {
+ "version": "0.18.1",
+ "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.1.tgz",
+ "integrity": "sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@wry/caches": "^1.0.0",
+ "@wry/context": "^0.7.0",
+ "@wry/trie": "^0.5.0",
+ "tslib": "^2.3.0"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -30170,6 +31138,104 @@
"node": ">=0.10.0"
}
},
+ "node_modules/pino": {
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/pino/-/pino-8.21.0.tgz",
+ "integrity": "sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==",
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0",
+ "fast-redact": "^3.1.1",
+ "on-exit-leak-free": "^2.1.0",
+ "pino-abstract-transport": "^1.2.0",
+ "pino-std-serializers": "^6.0.0",
+ "process-warning": "^3.0.0",
+ "quick-format-unescaped": "^4.0.3",
+ "real-require": "^0.2.0",
+ "safe-stable-stringify": "^2.3.1",
+ "sonic-boom": "^3.7.0",
+ "thread-stream": "^2.6.0"
+ },
+ "bin": {
+ "pino": "bin.js"
+ }
+ },
+ "node_modules/pino-abstract-transport": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz",
+ "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "^4.0.0",
+ "split2": "^4.0.0"
+ }
+ },
+ "node_modules/pino-abstract-transport/node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/pino-abstract-transport/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/pino-abstract-transport/node_modules/readable-stream": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
+ "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
+ "license": "MIT",
+ "dependencies": {
+ "abort-controller": "^3.0.0",
+ "buffer": "^6.0.3",
+ "events": "^3.3.0",
+ "process": "^0.11.10",
+ "string_decoder": "^1.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/pino-std-serializers": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz",
+ "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==",
+ "license": "MIT"
+ },
"node_modules/pirates": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
@@ -30641,6 +31707,12 @@
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"license": "MIT"
},
+ "node_modules/process-warning": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz",
+ "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==",
+ "license": "MIT"
+ },
"node_modules/progress-events": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.0.1.tgz",
@@ -30687,6 +31759,31 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/protobufjs": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz",
+ "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==",
+ "hasInstallScript": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/node": ">=13.7.0",
+ "long": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -30959,6 +32056,12 @@
"integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
"license": "MIT"
},
+ "node_modules/quick-format-unescaped": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
+ "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==",
+ "license": "MIT"
+ },
"node_modules/quick-lru": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
@@ -31398,6 +32501,15 @@
"node": ">=8.10.0"
}
},
+ "node_modules/real-require": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz",
+ "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12.13.0"
+ }
+ },
"node_modules/recma-build-jsx": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz",
@@ -31604,6 +32716,25 @@
"jsesc": "bin/jsesc"
}
},
+ "node_modules/rehackt": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.1.0.tgz",
+ "integrity": "sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==",
+ "license": "MIT",
+ "peer": true,
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "*"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/rehype-recma": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz",
@@ -32055,6 +33186,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safe-stable-stringify": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
+ "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/satori": {
"version": "0.12.2",
"resolved": "https://registry.npmjs.org/satori/-/satori-0.12.2.tgz",
@@ -32462,6 +33602,15 @@
"npm": ">= 3.0.0"
}
},
+ "node_modules/sonic-boom": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz",
+ "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==",
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0"
+ }
+ },
"node_modules/sort-object-keys": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz",
@@ -32597,6 +33746,7 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
"integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+ "dev": true,
"license": "Apache-2.0",
"dependencies": {
"spdx-expression-parse": "^3.0.0",
@@ -32607,12 +33757,14 @@
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+ "dev": true,
"license": "CC-BY-3.0"
},
"node_modules/spdx-expression-parse": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"spdx-exceptions": "^2.1.0",
@@ -32623,6 +33775,7 @@
"version": "3.0.22",
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz",
"integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==",
+ "dev": true,
"license": "CC0-1.0"
},
"node_modules/speed-limiter": {
@@ -32647,6 +33800,15 @@
"node": "*"
}
},
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -33117,6 +34279,19 @@
"node": ">= 6"
}
},
+ "node_modules/superjson": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
+ "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "copy-anything": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -33224,21 +34399,6 @@
}
}
},
- "node_modules/svelte-check/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
"node_modules/svelte-check/node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
@@ -33296,6 +34456,16 @@
"typescript": "^4.9.4 || ^5.0.0"
}
},
+ "node_modules/symbol-observable": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
+ "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/synckit": {
"version": "0.11.11",
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz",
@@ -33578,6 +34748,15 @@
"integrity": "sha512-oB7yIimd8SuGptespDAZnNkzIz+NWaJCu2RMsbs4Wmp9zSDUM8Nhi3s2OOcqYuv3mN4hitXc8DVx+LyUmbUDiA==",
"license": "ISC"
},
+ "node_modules/thread-stream": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.7.0.tgz",
+ "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==",
+ "license": "MIT",
+ "dependencies": {
+ "real-require": "^0.2.0"
+ }
+ },
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -33862,6 +35041,19 @@
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"license": "Apache-2.0"
},
+ "node_modules/ts-invariant": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz",
+ "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/ts-jest": {
"version": "29.4.4",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.4.tgz",
@@ -35098,6 +36290,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
"license": "Apache-2.0",
"dependencies": {
"spdx-correct": "^3.0.0",
@@ -35282,18 +36475,6 @@
}
}
},
- "node_modules/vite-plugin-top-level-await/node_modules/@swc/helpers": {
- "version": "0.5.17",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
- "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "peer": true,
- "dependencies": {
- "tslib": "^2.8.0"
- }
- },
"node_modules/vite-plugin-top-level-await/node_modules/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
@@ -36227,6 +37408,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
"integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"imurmurhash": "^0.1.4",
@@ -36240,6 +37422,7 @@
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/ws": {
@@ -36416,6 +37599,23 @@
"integrity": "sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==",
"license": "MIT"
},
+ "node_modules/zen-observable": {
+ "version": "0.8.15",
+ "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",
+ "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/zen-observable-ts": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz",
+ "integrity": "sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "zen-observable": "0.8.15"
+ }
+ },
"node_modules/zimmerframe": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
@@ -36528,18 +37728,6 @@
}
}
},
- "packages/bitcoin/node_modules/@swc/helpers": {
- "version": "0.5.17",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
- "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "peer": true,
- "dependencies": {
- "tslib": "^2.8.0"
- }
- },
"packages/configs": {
"name": "@meshsdk/configs",
"version": "0.0.0",
@@ -36918,18 +38106,6 @@
}
}
},
- "packages/mesh-hydra/node_modules/@swc/helpers": {
- "version": "0.5.17",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
- "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "peer": true,
- "dependencies": {
- "tslib": "^2.8.0"
- }
- },
"packages/mesh-provider": {
"name": "@meshsdk/provider",
"version": "1.9.0-beta.79",
@@ -37063,6 +38239,69 @@
"typescript": "^5.3.3"
}
},
+ "packages/midnight-setup": {
+ "name": "@meshsdk/midnight-setup",
+ "version": "1.9.0-beta.79",
+ "license": "MIT",
+ "dependencies": {
+ "@midnight-ntwrk/compact-runtime": "^0.8.1",
+ "@midnight-ntwrk/ledger": "^4.0.0",
+ "@midnight-ntwrk/midnight-js-contracts": "2.0.2",
+ "@midnight-ntwrk/midnight-js-types": "2.0.2",
+ "@midnight-ntwrk/zswap": "4.0.0",
+ "@radix-ui/react-dialog": "^1.1.14",
+ "@radix-ui/react-label": "^2.1.7",
+ "@radix-ui/react-progress": "^1.1.7",
+ "@radix-ui/react-slot": "^1.2.3",
+ "class-variance-authority": "^0.7.1",
+ "clsx": "^2.1.1",
+ "fp-ts": "^2.16.1",
+ "lucide-react": "^0.523.0",
+ "pino": "^8.16.1",
+ "rxjs": "^7.8.1",
+ "semver": "^7.6.0",
+ "tailwind-merge": "^3.3.1"
+ },
+ "devDependencies": {
+ "@meshsdk/configs": "*",
+ "@types/react": "^18.2.61",
+ "@types/react-dom": "^18.2.19",
+ "@types/ws": "^8.5.9",
+ "eslint": "^8.57.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "tsup": "^8.0.2",
+ "typescript": "^5.3.3"
+ },
+ "peerDependencies": {
+ "@midnight-ntwrk/dapp-connector-api": "^3.0.0",
+ "@midnight-ntwrk/midnight-js-fetch-zk-config-provider": "^2.0.2",
+ "@midnight-ntwrk/midnight-js-http-client-proof-provider": "^2.0.2",
+ "@midnight-ntwrk/midnight-js-indexer-public-data-provider": "^2.0.2",
+ "@midnight-ntwrk/midnight-js-level-private-state-provider": "^2.0.2",
+ "@midnight-ntwrk/midnight-js-network-id": "^2.0.2",
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "packages/midnight-setup/node_modules/tailwind-merge": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz",
+ "integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/dcastil"
+ }
+ },
"scripts/mesh-cli": {
"name": "meshjs",
"version": "1.9.0-beta.79",
diff --git a/packages/midnight-setup/.npmignore b/packages/midnight-setup/.npmignore
new file mode 100644
index 000000000..3fd026b50
--- /dev/null
+++ b/packages/midnight-setup/.npmignore
@@ -0,0 +1,33 @@
+# Development directories
+packages/
+compact/
+node_modules/
+src/
+
+# Build artifacts not needed
+.turbo
+
+# Yarn/workspace files (we use npm in main repo)
+yarn.lock
+turbo.json
+
+# Development configs
+tsconfig.json
+tsup.config.ts
+.eslintrc*
+.prettierrc*
+
+# Tests
+*.test.ts
+*.spec.ts
+test/
+tests/
+
+# Git
+.git
+.gitignore
+
+# Misc
+*.log
+.DS_Store
+
diff --git a/packages/midnight-setup/LICENSE b/packages/midnight-setup/LICENSE
new file mode 100644
index 000000000..f313fef23
--- /dev/null
+++ b/packages/midnight-setup/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 luislucena16
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/packages/midnight-setup/README.md b/packages/midnight-setup/README.md
new file mode 100644
index 000000000..30d1f59ea
--- /dev/null
+++ b/packages/midnight-setup/README.md
@@ -0,0 +1,1051 @@
+# @meshsdk/midnight-setup
+
+
+
🚀 The fastest way to build on Midnight Network
+
Pre-built smart contract + Complete API + Ready-to-use code snippets
+
+ [](https://www.npmjs.com/package/@meshsdk/midnight-setup)
+ [](https://opensource.org/licenses/MIT)
+ [](https://www.typescriptlang.org/)
+
+
+---
+
+## ⚡ Quick Start (2 minutes)
+
+### Step 1: Install
+
+```bash
+npm install @meshsdk/midnight-setup \
+ @midnight-ntwrk/dapp-connector-api@3.0.0 \
+ @midnight-ntwrk/midnight-js-fetch-zk-config-provider@2.0.2 \
+ @midnight-ntwrk/midnight-js-http-client-proof-provider@2.0.2 \
+ @midnight-ntwrk/midnight-js-indexer-public-data-provider@2.0.2 \
+ @midnight-ntwrk/midnight-js-level-private-state-provider@2.0.2 \
+ @midnight-ntwrk/midnight-js-network-id@2.0.2
+```
+
+**What happens automatically:**
+- ✅ ZK parameters are downloaded to `.cache/midnight/zk-params/`
+- ✅ All dependencies are installed
+- ✅ Your project is ready to use Midnight Network
+
+> **Note:** The ZK params download (~50MB) runs automatically after installation. If it fails, you can run it manually:
+> ```bash
+> sh node_modules/@meshsdk/midnight-setup/fetch-zk-params.sh
+> ```
+
+### Step 2: Install Lace Beta Wallet
+
+Download and install: [Lace Beta Wallet for Midnight](https://chromewebstore.google.com/detail/lace-beta/djcdfchkaijggdjokfomholkalbffgil)
+
+1. Create a new wallet
+2. Switch to **Midnight Testnet** in settings
+3. Make sure you have at least one account
+
+### Step 3: Setup Your Project (Copy Required Files)
+
+See the **"🎯 Complete Hello World"** section below for all the files you need to copy.
+
+### Step 4: Run Your dApp
+
+```bash
+npm run dev
+```
+
+Open http://localhost:5173 and click "Deploy New Contract"
+
+**That's it! You have a working Midnight dApp!** 🎉
+
+---
+
+## 🚀 Quick Deploy - One Code Block
+
+```typescript
+import { MidnightSetupAPI } from '@meshsdk/midnight-setup';
+import { setupProviders } from './providers'; // See below ⬇️
+
+async function deployMyContract() {
+ // 1. Setup providers (wallet connection)
+ const providers = await setupProviders();
+
+ // 2. Deploy contract
+ const api = await MidnightSetupAPI.deployMidnightSetupContract(providers);
+
+ // 3. Read the state
+ const state = await api.getLedgerState();
+
+ console.log('✅ Contract deployed at:', api.deployedContractAddress);
+ console.log('💬 Message:', state.ledgerState?.message);
+ // Output: "Made with ❤️ by MeshJS team!"
+}
+```
+
+---
+
+## 🎯 Complete Hello World - Copy & Paste These Files
+
+Here's a **complete working dApp** you can copy and paste. Create these files in your project:
+
+### File Structure
+```
+my-midnight-dapp/
+├── src/
+│ ├── lib/
+│ │ └── providers.ts ← Copy this
+│ ├── hooks/
+│ │ └── useMidnightContract.ts ← Copy this
+│ ├── App.tsx ← Copy this
+│ ├── polyfills.ts ← Copy this
+│ └── main.tsx ← Update this
+├── index.html
+├── vite.config.ts ← Update this
+└── package.json
+```
+
+### 📄 File 1: `src/polyfills.ts`
+```typescript
+import { Buffer } from 'buffer';
+
+window.Buffer = Buffer;
+window.global = window.global || window;
+window.process = window.process || { env: {} };
+
+export { Buffer };
+```
+
+### 📄 File 2: `src/lib/providers.ts`
+```typescript
+import { levelPrivateStateProvider } from '@midnight-ntwrk/midnight-js-level-private-state-provider';
+import { FetchZkConfigProvider } from '@midnight-ntwrk/midnight-js-fetch-zk-config-provider';
+import { httpClientProofProvider } from '@midnight-ntwrk/midnight-js-http-client-proof-provider';
+import { indexerPublicDataProvider } from '@midnight-ntwrk/midnight-js-indexer-public-data-provider';
+import type { MidnightSetupContractProviders } from '@meshsdk/midnight-setup';
+
+export async function setupProviders(): Promise {
+ // Connect to Lace Wallet
+ const wallet = window.midnight?.mnLace;
+ if (!wallet) {
+ throw new Error('Please install Lace Beta Wallet for Midnight Network');
+ }
+
+ // Enable wallet and get state
+ const walletAPI = await wallet.enable();
+ const walletState = await walletAPI.state();
+ const uris = await wallet.serviceUriConfig();
+
+ return {
+ privateStateProvider: levelPrivateStateProvider({
+ privateStateStoreName: 'my-dapp-state',
+ }),
+ zkConfigProvider: new FetchZkConfigProvider(
+ window.location.origin,
+ fetch.bind(window)
+ ),
+ proofProvider: httpClientProofProvider(uris.proverServerUri),
+ publicDataProvider: indexerPublicDataProvider(
+ uris.indexerUri,
+ uris.indexerWsUri
+ ),
+ walletProvider: {
+ coinPublicKey: walletState.coinPublicKey,
+ encryptionPublicKey: walletState.encryptionPublicKey,
+ balanceTx: (tx, newCoins) => {
+ return walletAPI.balanceAndProveTransaction(tx, newCoins);
+ },
+ },
+ midnightProvider: {
+ submitTx: (tx) => {
+ return walletAPI.submitTransaction(tx);
+ },
+ },
+ };
+}
+
+// TypeScript declaration for window.midnight
+declare global {
+ interface Window {
+ midnight?: {
+ mnLace?: any;
+ };
+ }
+}
+```
+
+### 📄 File 3: `src/hooks/useMidnightContract.ts`
+```typescript
+import { useState, useCallback } from 'react';
+import { MidnightSetupAPI, type DeployedMidnightSetupAPI } from '@meshsdk/midnight-setup';
+import { setupProviders } from '../lib/providers';
+
+export function useMidnightContract() {
+ const [api, setApi] = useState(null);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState(null);
+
+ const deployContract = useCallback(async () => {
+ setLoading(true);
+ setError(null);
+ try {
+ const providers = await setupProviders();
+ const newApi = await MidnightSetupAPI.deployMidnightSetupContract(providers);
+ setApi(newApi);
+ return newApi;
+ } catch (err) {
+ const message = err instanceof Error ? err.message : 'Failed to deploy';
+ setError(message);
+ throw err;
+ } finally {
+ setLoading(false);
+ }
+ }, []);
+
+ const joinContract = useCallback(async (address: string) => {
+ setLoading(true);
+ setError(null);
+ try {
+ const providers = await setupProviders();
+ const newApi = await MidnightSetupAPI.joinMidnightSetupContract(providers, address);
+ setApi(newApi);
+ return newApi;
+ } catch (err) {
+ const message = err instanceof Error ? err.message : 'Failed to join';
+ setError(message);
+ throw err;
+ } finally {
+ setLoading(false);
+ }
+ }, []);
+
+ return {
+ api,
+ loading,
+ error,
+ deployContract,
+ joinContract,
+ };
+}
+```
+
+### 📄 File 4: `src/App.tsx`
+```typescript
+import { useState, useEffect } from 'react';
+import { useMidnightContract } from './hooks/useMidnightContract';
+
+function App() {
+ const { api, loading, error, deployContract, joinContract } = useMidnightContract();
+ const [message, setMessage] = useState('');
+ const [contractAddress, setContractAddress] = useState('');
+
+ // Read contract state when API is ready
+ useEffect(() => {
+ if (api) {
+ api.getLedgerState().then(state => {
+ setMessage(state.ledgerState?.message || '');
+ });
+ }
+ }, [api]);
+
+ return (
+
+
+
+ 🌙 My Midnight dApp
+
+
+ Built with @meshsdk/midnight-setup
+
+
+ {/* Deploy new contract */}
+ {!api && (
+
+
{
+ if (!loading) e.currentTarget.style.transform = 'scale(1.02)';
+ }}
+ onMouseLeave={(e) => {
+ e.currentTarget.style.transform = 'scale(1)';
+ }}
+ >
+ {loading ? '⏳ Deploying...' : '🚀 Deploy New Contract'}
+
+
+
+
+ Or join existing contract:
+
+
+ setContractAddress(e.target.value)}
+ style={{
+ flex: 1,
+ padding: '10px',
+ fontSize: '14px',
+ border: '2px solid #e0e0e0',
+ borderRadius: '6px',
+ outline: 'none'
+ }}
+ onFocus={(e) => e.currentTarget.style.borderColor = '#667eea'}
+ onBlur={(e) => e.currentTarget.style.borderColor = '#e0e0e0'}
+ />
+ joinContract(contractAddress)}
+ disabled={loading || !contractAddress}
+ style={{
+ padding: '10px 20px',
+ fontSize: '14px',
+ fontWeight: '600',
+ color: 'white',
+ background: (loading || !contractAddress) ? '#ccc' : '#667eea',
+ border: 'none',
+ borderRadius: '6px',
+ cursor: (loading || !contractAddress) ? 'not-allowed' : 'pointer',
+ }}
+ >
+ Join
+
+
+
+
+ )}
+
+ {/* Show error */}
+ {error && (
+
+ ❌ {error}
+
+ )}
+
+ {/* Show contract info */}
+ {api && (
+
+
+ ✅ Contract Connected
+
+
+
+ 📍 Address:
+
+ {api.deployedContractAddress}
+
+
+
+ 💬 Message:
+
+ {message || 'Loading...'}
+
+
+
+
+ )}
+
+
+ Made with ❤️ by MeshJS Team
+
+
+
+ );
+}
+
+export default App;
+```
+
+### 📄 File 5: `src/main.tsx`
+```typescript
+import './polyfills'; // ← Add this FIRST
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App';
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+
+);
+```
+
+### 📄 File 6: `vite.config.ts`
+```typescript
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig({
+ plugins: [react()],
+ define: {
+ 'global': 'globalThis',
+ },
+ resolve: {
+ alias: {
+ buffer: 'buffer',
+ process: 'process/browser',
+ },
+ },
+});
+```
+
+### 📄 File 7: `package.json` dependencies
+```json
+{
+ "dependencies": {
+ "@meshsdk/midnight-setup": "^1.0.0",
+ "@midnight-ntwrk/dapp-connector-api": "3.0.0",
+ "@midnight-ntwrk/midnight-js-fetch-zk-config-provider": "2.0.2",
+ "@midnight-ntwrk/midnight-js-http-client-proof-provider": "2.0.2",
+ "@midnight-ntwrk/midnight-js-indexer-public-data-provider": "2.0.2",
+ "@midnight-ntwrk/midnight-js-level-private-state-provider": "2.0.2",
+ "@midnight-ntwrk/midnight-js-network-id": "2.0.2",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "buffer": "^6.0.3",
+ "process": "^0.11.10"
+ }
+}
+```
+
+### 🚀 Run Your dApp
+
+```bash
+# 1. Install all dependencies
+npm install
+
+# 2. Start development server
+npm run dev
+
+# 3. Open http://localhost:5173 in your browser
+# 4. Make sure Lace Beta Wallet is installed
+# 5. Click "Deploy New Contract"
+```
+
+**That's it!** You now have a fully working Midnight Network dApp. 🎉
+
+---
+
+## 📋 Ready-to-Use Code Snippets
+
+### 1. Provider Setup (Copy this helper function)
+
+Create `src/lib/providers.ts`:
+
+```typescript
+import { levelPrivateStateProvider } from '@midnight-ntwrk/midnight-js-level-private-state-provider';
+import { FetchZkConfigProvider } from '@midnight-ntwrk/midnight-js-fetch-zk-config-provider';
+import { httpClientProofProvider } from '@midnight-ntwrk/midnight-js-http-client-proof-provider';
+import { indexerPublicDataProvider } from '@midnight-ntwrk/midnight-js-indexer-public-data-provider';
+import type { MidnightSetupContractProviders } from '@meshsdk/midnight-setup';
+
+export async function setupProviders(): Promise {
+ // Connect to Lace Wallet
+ const wallet = window.midnight?.mnLace;
+ if (!wallet) {
+ throw new Error('Please install Lace Beta Wallet for Midnight Network');
+ }
+
+ // Enable wallet and get state
+ const walletAPI = await wallet.enable();
+ const walletState = await walletAPI.state();
+ const uris = await wallet.serviceUriConfig();
+
+ return {
+ privateStateProvider: levelPrivateStateProvider({
+ privateStateStoreName: 'my-dapp-state',
+ }),
+ zkConfigProvider: new FetchZkConfigProvider(
+ window.location.origin,
+ fetch.bind(window)
+ ),
+ proofProvider: httpClientProofProvider(uris.proverServerUri),
+ publicDataProvider: indexerPublicDataProvider(
+ uris.indexerUri,
+ uris.indexerWsUri
+ ),
+ walletProvider: {
+ coinPublicKey: walletState.coinPublicKey,
+ encryptionPublicKey: walletState.encryptionPublicKey,
+ balanceTx: (tx, newCoins) => {
+ return walletAPI.balanceAndProveTransaction(tx, newCoins);
+ },
+ },
+ midnightProvider: {
+ submitTx: (tx) => {
+ return walletAPI.submitTransaction(tx);
+ },
+ },
+ };
+}
+```
+
+**Save this file once, use it everywhere in your project.** ✅
+
+---
+
+### 2. React Hook (Copy & Paste - Production Ready)
+
+Create `src/hooks/useMidnightContract.ts`:
+
+```typescript
+import { useState, useCallback } from 'react';
+import { MidnightSetupAPI, type DeployedMidnightSetupAPI } from '@meshsdk/midnight-setup';
+import { setupProviders } from '../lib/providers';
+
+export function useMidnightContract() {
+ const [api, setApi] = useState(null);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState(null);
+
+ const deployContract = useCallback(async () => {
+ setLoading(true);
+ setError(null);
+ try {
+ const providers = await setupProviders();
+ const newApi = await MidnightSetupAPI.deployMidnightSetupContract(providers);
+ setApi(newApi);
+ return newApi;
+ } catch (err) {
+ const message = err instanceof Error ? err.message : 'Failed to deploy';
+ setError(message);
+ throw err;
+ } finally {
+ setLoading(false);
+ }
+ }, []);
+
+ const joinContract = useCallback(async (address: string) => {
+ setLoading(true);
+ setError(null);
+ try {
+ const providers = await setupProviders();
+ const newApi = await MidnightSetupAPI.joinMidnightSetupContract(providers, address);
+ setApi(newApi);
+ return newApi;
+ } catch (err) {
+ const message = err instanceof Error ? err.message : 'Failed to join';
+ setError(message);
+ throw err;
+ } finally {
+ setLoading(false);
+ }
+ }, []);
+
+ return {
+ api,
+ loading,
+ error,
+ deployContract,
+ joinContract,
+ };
+}
+```
+
+**Usage in your component:**
+
+```typescript
+import { useMidnightContract } from './hooks/useMidnightContract';
+
+function MyComponent() {
+ const { api, loading, error, deployContract } = useMidnightContract();
+
+ return (
+
+
+ {loading ? 'Deploying...' : 'Deploy Contract'}
+
+ {error &&
Error: {error}
}
+ {api &&
Contract: {api.deployedContractAddress}
}
+
+ );
+}
+```
+
+---
+
+### 3. Complete React Component (Copy & Run)
+
+```typescript
+import { useState, useEffect } from 'react';
+import { useMidnightContract } from './hooks/useMidnightContract';
+
+export function MidnightDApp() {
+ const { api, loading, error, deployContract, joinContract } = useMidnightContract();
+ const [message, setMessage] = useState('');
+ const [contractAddress, setContractAddress] = useState('');
+
+ // Read contract state when API is ready
+ useEffect(() => {
+ if (api) {
+ api.getLedgerState().then(state => {
+ setMessage(state.ledgerState?.message || '');
+ });
+ }
+ }, [api]);
+
+ return (
+
+
My Midnight dApp
+
+ {/* Deploy new contract */}
+
+
+ {loading ? 'Deploying...' : 'Deploy New Contract'}
+
+
+ {/* Or join existing */}
+
+ setContractAddress(e.target.value)}
+ style={{ padding: '8px', width: '300px' }}
+ />
+ joinContract(contractAddress)}
+ disabled={loading || !contractAddress || !!api}
+ style={{ padding: '8px 16px', marginLeft: '10px' }}
+ >
+ Join Contract
+
+
+
+
+ {/* Show error */}
+ {error && (
+
+ Error: {error}
+
+ )}
+
+ {/* Show contract info */}
+ {api && (
+
+
✅ Contract Ready
+
Address: {api.deployedContractAddress}
+
Message: {message}
+
+ )}
+
+ );
+}
+```
+
+**This component is production-ready. Just import and use it!** 🎉
+
+---
+
+## 🔥 Common Use Cases (Copy These)
+
+### Deploy and Save Address
+
+```typescript
+const api = await MidnightSetupAPI.deployMidnightSetupContract(providers);
+
+// Save to localStorage for later use
+localStorage.setItem('myContractAddress', api.deployedContractAddress);
+
+console.log('✅ Deployed:', api.deployedContractAddress);
+```
+
+### Load Existing Contract
+
+```typescript
+const savedAddress = localStorage.getItem('myContractAddress');
+
+if (savedAddress) {
+ const api = await MidnightSetupAPI.joinMidnightSetupContract(
+ providers,
+ savedAddress
+ );
+ console.log('✅ Reconnected to contract');
+}
+```
+
+### Read Contract State
+
+```typescript
+// Get full contract state
+const contractState = await api.getContractState();
+console.log('Raw data:', contractState.data);
+console.log('Block:', contractState.blockHeight);
+
+// Get parsed ledger state (easier to use)
+const ledgerState = await api.getLedgerState();
+console.log('Message:', ledgerState.ledgerState?.message);
+```
+
+### Listen to State Changes (Real-time)
+
+```typescript
+api.state.subscribe({
+ next: (state) => {
+ console.log('State updated:', state);
+ // Update your UI here
+ },
+ error: (err) => {
+ console.error('State error:', err);
+ }
+});
+```
+
+### With Logging (for Development)
+
+```typescript
+import pino from 'pino';
+
+const logger = pino({ level: 'debug' });
+
+const api = await MidnightSetupAPI.deployMidnightSetupContract(
+ providers,
+ logger
+);
+
+// Now you'll see detailed logs in console
+```
+
+---
+
+## 🎨 Next.js Example (App Router)
+
+Create `app/midnight/page.tsx`:
+
+```typescript
+'use client';
+
+import { useState } from 'react';
+import { MidnightSetupAPI } from '@meshsdk/midnight-setup';
+import { setupProviders } from '@/lib/providers';
+
+export default function MidnightPage() {
+ const [status, setStatus] = useState('');
+
+ const deployContract = async () => {
+ try {
+ setStatus('Deploying...');
+
+ const providers = await setupProviders();
+ const api = await MidnightSetupAPI.deployMidnightSetupContract(providers);
+
+ setStatus(`✅ Deployed at: ${api.deployedContractAddress}`);
+ } catch (error) {
+ setStatus(`❌ Error: ${error.message}`);
+ }
+ };
+
+ return (
+
+ Midnight dApp
+
+ Deploy Contract
+
+ {status && {status}
}
+
+ );
+}
+```
+
+---
+
+## 🛠️ Vite + React Setup
+
+### 1. Install Vite polyfills
+
+```bash
+npm install buffer process
+```
+
+### 2. Create `src/polyfills.ts`:
+
+```typescript
+import { Buffer } from 'buffer';
+
+window.Buffer = Buffer;
+window.global = window.global || window;
+window.process = window.process || { env: {} };
+
+export { Buffer };
+```
+
+### 3. Import in `src/main.tsx`:
+
+```typescript
+import './polyfills'; // Add this first
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App';
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+
+);
+```
+
+### 4. Update `vite.config.ts`:
+
+```typescript
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig({
+ plugins: [react()],
+ define: {
+ 'global': 'globalThis',
+ },
+ resolve: {
+ alias: {
+ buffer: 'buffer',
+ process: 'process/browser',
+ },
+ },
+});
+```
+
+---
+
+## 📦 What's Included
+
+This package gives you everything you need:
+
+- ✅ **Pre-compiled Smart Contract** - No need to learn Compact
+- ✅ **Complete TypeScript API** - Full type safety
+- ✅ **Wallet Integration** - Works with Lace Beta Wallet
+- ✅ **State Management** - Private & public state handling
+- ✅ **Zero Configuration** - Just install and use
+
+---
+
+## 📚 API Reference
+
+### `MidnightSetupAPI.deployMidnightSetupContract(providers, logger?)`
+
+Deploy a new contract.
+
+**Parameters:**
+- `providers: MidnightSetupContractProviders` - Required (see provider setup above)
+- `logger?: Logger` - Optional Pino logger
+
+**Returns:** `Promise`
+
+**Example:**
+```typescript
+const api = await MidnightSetupAPI.deployMidnightSetupContract(providers);
+```
+
+---
+
+### `MidnightSetupAPI.joinMidnightSetupContract(providers, address, logger?)`
+
+Connect to existing contract.
+
+**Parameters:**
+- `providers: MidnightSetupContractProviders` - Required
+- `address: string` - Contract address
+- `logger?: Logger` - Optional
+
+**Returns:** `Promise`
+
+**Example:**
+```typescript
+const api = await MidnightSetupAPI.joinMidnightSetupContract(
+ providers,
+ '0x123abc...'
+);
+```
+
+---
+
+### `api.getContractState()`
+
+Get raw contract state.
+
+**Returns:** `Promise`
+
+```typescript
+const state = await api.getContractState();
+// {
+// address: string,
+// data: unknown,
+// blockHeight?: string,
+// blockHash?: string,
+// error?: string
+// }
+```
+
+---
+
+### `api.getLedgerState()`
+
+Get parsed ledger state.
+
+**Returns:** `Promise`
+
+```typescript
+const ledger = await api.getLedgerState();
+// {
+// address: string,
+// ledgerState?: {
+// message: string | null
+// },
+// blockHeight?: string,
+// error?: string
+// }
+```
+
+---
+
+### `api.deployedContractAddress`
+
+Get contract address.
+
+**Type:** `string`
+
+```typescript
+console.log(api.deployedContractAddress);
+// "0x123abc..."
+```
+
+---
+
+### `api.state`
+
+Observable for state changes.
+
+**Type:** `Observable`
+
+```typescript
+api.state.subscribe(state => {
+ console.log('New state:', state);
+});
+```
+
+---
+
+## 🔐 TypeScript Types
+
+All types are fully exported:
+
+```typescript
+import type {
+ MidnightSetupAPI,
+ DeployedMidnightSetupAPI,
+ MidnightSetupContractProviders,
+ ContractStateData,
+ LedgerStateData,
+ DerivedMidnightSetupContractState,
+ TokenCircuitKeys,
+} from '@meshsdk/midnight-setup';
+```
+
+---
+
+## 🔗 Resources
+
+- 📖 [Midnight Network Docs](https://docs.midnight.network)
+- 💬 [MeshJS Discord](https://discord.gg/meshjs)
+- 🐛 [Report Issues](https://github.com/MeshJS/midnight-setup/issues)
+- 💻 [Source Code](https://github.com/MeshJS/midnight-setup)
+- 🌐 [MeshJS Website](https://meshjs.dev)
+
+---
+
+## 📄 License
+
+MIT © [MeshJS Team](https://github.com/MeshJS)
+
+---
+
+## ⚡ Start Building Now
+
+```bash
+npm install @meshsdk/midnight-setup
+```
+
+Copy the code snippets above and start building your Midnight dApp in minutes! 🚀
+
+**Questions?** [Open an issue](https://github.com/MeshJS/midnight-setup/issues) and we'll help you.
+
+---
+
+
diff --git a/packages/midnight-setup/contract-compiled/index.d.ts b/packages/midnight-setup/contract-compiled/index.d.ts
new file mode 100644
index 000000000..a7bd1562b
--- /dev/null
+++ b/packages/midnight-setup/contract-compiled/index.d.ts
@@ -0,0 +1 @@
+export * from "./managed/midnight-setup/contract/index.cjs";
diff --git a/packages/midnight-setup/contract-compiled/index.js b/packages/midnight-setup/contract-compiled/index.js
new file mode 100644
index 000000000..3a40c7940
--- /dev/null
+++ b/packages/midnight-setup/contract-compiled/index.js
@@ -0,0 +1,2 @@
+export * from "./managed/midnight-setup/contract/index.cjs";
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/packages/midnight-setup/contract-compiled/index.js.map b/packages/midnight-setup/contract-compiled/index.js.map
new file mode 100644
index 000000000..002bb8f0b
--- /dev/null
+++ b/packages/midnight-setup/contract-compiled/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,6CAA6C,CAAC"}
\ No newline at end of file
diff --git a/packages/midnight-setup/contract-compiled/managed/midnight-setup/compiler/contract-info.json b/packages/midnight-setup/contract-compiled/managed/midnight-setup/compiler/contract-info.json
new file mode 100644
index 000000000..929962bf5
--- /dev/null
+++ b/packages/midnight-setup/contract-compiled/managed/midnight-setup/compiler/contract-info.json
@@ -0,0 +1,8 @@
+{
+ "circuits": [
+ ],
+ "witnesses": [
+ ],
+ "contracts": [
+ ]
+}
diff --git a/packages/midnight-setup/contract-compiled/managed/midnight-setup/contract/index.cjs b/packages/midnight-setup/contract-compiled/managed/midnight-setup/contract/index.cjs
new file mode 100644
index 000000000..615aeba27
--- /dev/null
+++ b/packages/midnight-setup/contract-compiled/managed/midnight-setup/contract/index.cjs
@@ -0,0 +1,180 @@
+'use strict';
+const __compactRuntime = require('@midnight-ntwrk/compact-runtime');
+const expectedRuntimeVersionString = '0.8.1';
+const expectedRuntimeVersion = expectedRuntimeVersionString.split('-')[0].split('.').map(Number);
+const actualRuntimeVersion = __compactRuntime.versionString.split('-')[0].split('.').map(Number);
+if (expectedRuntimeVersion[0] != actualRuntimeVersion[0]
+ || (actualRuntimeVersion[0] == 0 && expectedRuntimeVersion[1] != actualRuntimeVersion[1])
+ || expectedRuntimeVersion[1] > actualRuntimeVersion[1]
+ || (expectedRuntimeVersion[1] == actualRuntimeVersion[1] && expectedRuntimeVersion[2] > actualRuntimeVersion[2]))
+ throw new __compactRuntime.CompactError(`Version mismatch: compiled code expects ${expectedRuntimeVersionString}, runtime is ${__compactRuntime.versionString}`);
+{ const MAX_FIELD = 52435875175126190479447740508185965837690552500527637822603658699938581184512n;
+ if (__compactRuntime.MAX_FIELD !== MAX_FIELD)
+ throw new __compactRuntime.CompactError(`compiler thinks maximum field value is ${MAX_FIELD}; run time thinks it is ${__compactRuntime.MAX_FIELD}`)
+}
+
+const _descriptor_0 = new __compactRuntime.CompactTypeUnsignedInteger(18446744073709551615n, 8);
+
+const _descriptor_1 = new __compactRuntime.CompactTypeBoolean();
+
+const _descriptor_2 = new __compactRuntime.CompactTypeBytes(32);
+
+class _ContractAddress_0 {
+ alignment() {
+ return _descriptor_2.alignment();
+ }
+ fromValue(value_0) {
+ return {
+ bytes: _descriptor_2.fromValue(value_0)
+ }
+ }
+ toValue(value_0) {
+ return _descriptor_2.toValue(value_0.bytes);
+ }
+}
+
+const _descriptor_3 = new _ContractAddress_0();
+
+const _descriptor_4 = new __compactRuntime.CompactTypeUnsignedInteger(255n, 1);
+
+const _descriptor_5 = new __compactRuntime.CompactTypeUnsignedInteger(340282366920938463463374607431768211455n, 16);
+
+class Contract {
+ witnesses;
+ constructor(...args_0) {
+ if (args_0.length !== 1) {
+ throw new __compactRuntime.CompactError(`Contract constructor: expected 1 argument, received ${args_0.length}`);
+ }
+ const witnesses_0 = args_0[0];
+ if (typeof(witnesses_0) !== 'object') {
+ throw new __compactRuntime.CompactError('first (witnesses) argument to Contract constructor is not an object');
+ }
+ this.witnesses = witnesses_0;
+ this.circuits = {
+ };
+ this.impureCircuits = {};
+ }
+ initialState(...args_0) {
+ if (args_0.length !== 1) {
+ throw new __compactRuntime.CompactError(`Contract state constructor: expected 1 argument (as invoked from Typescript), received ${args_0.length}`);
+ }
+ const constructorContext_0 = args_0[0];
+ if (typeof(constructorContext_0) !== 'object') {
+ throw new __compactRuntime.CompactError(`Contract state constructor: expected 'constructorContext' in argument 1 (as invoked from Typescript) to be an object`);
+ }
+ if (!('initialZswapLocalState' in constructorContext_0)) {
+ throw new __compactRuntime.CompactError(`Contract state constructor: expected 'initialZswapLocalState' in argument 1 (as invoked from Typescript)`);
+ }
+ if (typeof(constructorContext_0.initialZswapLocalState) !== 'object') {
+ throw new __compactRuntime.CompactError(`Contract state constructor: expected 'initialZswapLocalState' in argument 1 (as invoked from Typescript) to be an object`);
+ }
+ const state_0 = new __compactRuntime.ContractState();
+ let stateValue_0 = __compactRuntime.StateValue.newArray();
+ stateValue_0 = stateValue_0.arrayPush(__compactRuntime.StateValue.newNull());
+ state_0.data = stateValue_0;
+ const context = {
+ originalState: state_0,
+ currentPrivateState: constructorContext_0.initialPrivateState,
+ currentZswapLocalState: constructorContext_0.initialZswapLocalState,
+ transactionContext: new __compactRuntime.QueryContext(state_0.data, __compactRuntime.dummyContractAddress())
+ };
+ const partialProofData = {
+ input: { value: [], alignment: [] },
+ output: undefined,
+ publicTranscript: [],
+ privateTranscriptOutputs: []
+ };
+ Contract._query(context,
+ partialProofData,
+ [
+ { push: { storage: false,
+ value: __compactRuntime.StateValue.newCell({ value: _descriptor_4.toValue(0n),
+ alignment: _descriptor_4.alignment() }).encode() } },
+ { push: { storage: true,
+ value: __compactRuntime.StateValue.newCell({ value: _descriptor_2.toValue(new Uint8Array(32)),
+ alignment: _descriptor_2.alignment() }).encode() } },
+ { ins: { cached: false, n: 1 } }]);
+ Contract._query(context,
+ partialProofData,
+ [
+ { push: { storage: false,
+ value: __compactRuntime.StateValue.newCell({ value: _descriptor_4.toValue(0n),
+ alignment: _descriptor_4.alignment() }).encode() } },
+ { push: { storage: true,
+ value: __compactRuntime.StateValue.newCell({ value: _descriptor_2.toValue(new Uint8Array([77, 97, 100, 101, 32, 119, 105, 116, 104, 32, 226, 157, 164, 239, 184, 143, 32, 98, 121, 32, 77, 101, 115, 104, 74, 83, 32, 116, 101, 97, 109, 33])),
+ alignment: _descriptor_2.alignment() }).encode() } },
+ { ins: { cached: false, n: 1 } }]);
+ state_0.data = context.transactionContext.state;
+ return {
+ currentContractState: state_0,
+ currentPrivateState: context.currentPrivateState,
+ currentZswapLocalState: context.currentZswapLocalState
+ }
+ }
+ static _query(context, partialProofData, prog) {
+ var res;
+ try {
+ res = context.transactionContext.query(prog, __compactRuntime.CostModel.dummyCostModel());
+ } catch (err) {
+ throw new __compactRuntime.CompactError(err.toString());
+ }
+ context.transactionContext = res.context;
+ var reads = res.events.filter((e) => e.tag === 'read');
+ var i = 0;
+ partialProofData.publicTranscript = partialProofData.publicTranscript.concat(prog.map((op) => {
+ if(typeof(op) === 'object' && 'popeq' in op) {
+ return { popeq: {
+ ...op.popeq,
+ result: reads[i++].content,
+ } };
+ } else {
+ return op;
+ }
+ }));
+ if(res.events.length == 1 && res.events[0].tag === 'read') {
+ return res.events[0].content;
+ } else {
+ return res.events;
+ }
+ }
+}
+function ledger(state) {
+ const context = {
+ originalState: state,
+ transactionContext: new __compactRuntime.QueryContext(state, __compactRuntime.dummyContractAddress())
+ };
+ const partialProofData = {
+ input: { value: [], alignment: [] },
+ output: undefined,
+ publicTranscript: [],
+ privateTranscriptOutputs: []
+ };
+ return {
+ get message() {
+ return _descriptor_2.fromValue(Contract._query(context,
+ partialProofData,
+ [
+ { dup: { n: 0 } },
+ { idx: { cached: false,
+ pushPath: false,
+ path: [
+ { tag: 'value',
+ value: { value: _descriptor_4.toValue(0n),
+ alignment: _descriptor_4.alignment() } }] } },
+ { popeq: { cached: false,
+ result: undefined } }]).value);
+ }
+ };
+}
+const _emptyContext = {
+ originalState: new __compactRuntime.ContractState(),
+ transactionContext: new __compactRuntime.QueryContext(new __compactRuntime.ContractState().data, __compactRuntime.dummyContractAddress())
+};
+const _dummyContract = new Contract({ });
+const pureCircuits = {};
+const contractReferenceLocations = { tag: 'publicLedgerArray', indices: { } };
+exports.Contract = Contract;
+exports.ledger = ledger;
+exports.pureCircuits = pureCircuits;
+exports.contractReferenceLocations = contractReferenceLocations;
+//# sourceMappingURL=index.cjs.map
diff --git a/packages/midnight-setup/contract-compiled/managed/midnight-setup/contract/index.cjs.map b/packages/midnight-setup/contract-compiled/managed/midnight-setup/contract/index.cjs.map
new file mode 100644
index 000000000..ddeda7d98
--- /dev/null
+++ b/packages/midnight-setup/contract-compiled/managed/midnight-setup/contract/index.cjs.map
@@ -0,0 +1,8 @@
+{
+ "version": 3,
+ "file": "index.cjs",
+ "sourceRoot": "../../../../",
+ "sources": ["src/midnight-setup.compact"],
+ "names": [],
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMA;;;;;;;;;;;;GAEC;EAFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAFA;;;;;;;;;uDAAiC;IAG/B;;;;;;;;;uDAAO;;;;;;;GACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAJD;qCAAA;;;;;;;;;;;wFAAiC;KAAA;;;;;;;;;;;;;;"
+}
diff --git a/packages/midnight-setup/contract-compiled/managed/midnight-setup/contract/index.d.cts b/packages/midnight-setup/contract-compiled/managed/midnight-setup/contract/index.d.cts
new file mode 100644
index 000000000..14f6a203c
--- /dev/null
+++ b/packages/midnight-setup/contract-compiled/managed/midnight-setup/contract/index.d.cts
@@ -0,0 +1,32 @@
+import type * as __compactRuntime from '@midnight-ntwrk/compact-runtime';
+
+export type Witnesses = {
+}
+
+export type ImpureCircuits = {
+}
+
+export type PureCircuits = {
+}
+
+export type Circuits = {
+}
+
+export type Ledger = {
+ readonly message: Uint8Array;
+}
+
+export type ContractReferenceLocations = any;
+
+export declare const contractReferenceLocations : ContractReferenceLocations;
+
+export declare class Contract = Witnesses> {
+ witnesses: W;
+ circuits: Circuits;
+ impureCircuits: ImpureCircuits;
+ constructor(witnesses: W);
+ initialState(context: __compactRuntime.ConstructorContext): __compactRuntime.ConstructorResult;
+}
+
+export declare function ledger(state: __compactRuntime.StateValue): Ledger;
+export declare const pureCircuits: PureCircuits;
diff --git a/packages/midnight-setup/contract-compiled/midnight-setup.compact b/packages/midnight-setup/contract-compiled/midnight-setup.compact
new file mode 100644
index 000000000..ee012e9dc
--- /dev/null
+++ b/packages/midnight-setup/contract-compiled/midnight-setup.compact
@@ -0,0 +1,9 @@
+pragma language_version >= 0.17.0;
+
+import CompactStandardLibrary;
+
+export ledger message: Bytes<32>;
+
+constructor() {
+ message = "Made with ❤️ by MeshJS team!";
+}
\ No newline at end of file
diff --git a/packages/midnight-setup/package.json b/packages/midnight-setup/package.json
new file mode 100644
index 000000000..2c7fb56ae
--- /dev/null
+++ b/packages/midnight-setup/package.json
@@ -0,0 +1,101 @@
+{
+ "name": "@meshsdk/midnight-setup",
+ "version": "1.9.0-beta.79",
+ "description": "Midnight Network integration for MeshSDK - https://meshjs.dev/midnight",
+ "main": "./dist/index.cjs",
+ "browser": "./dist/index.js",
+ "module": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "type": "module",
+ "exports": {
+ ".": {
+ "types": "./dist/index.d.ts",
+ "import": "./dist/index.js",
+ "require": "./dist/index.cjs"
+ },
+ "./react": {
+ "types": "./dist/react.d.ts",
+ "import": "./dist/react.js",
+ "require": "./dist/react.cjs"
+ },
+ "./styles.css": "./dist/styles.css"
+ },
+ "files": [
+ "dist/**",
+ "contract-compiled/**"
+ ],
+ "scripts": {
+ "build:mesh": "tsup src/index.ts src/react.ts --format esm,cjs --dts && cp src/react/styles.css dist/styles.css",
+ "clean": "rm -rf .turbo && rm -rf dist && rm -rf node_modules",
+ "dev": "tsup src/index.ts src/react.ts --format esm,cjs --watch --dts",
+ "format": "prettier --check . --ignore-path ../../.gitignore",
+ "lint": "eslint",
+ "pack": "npm pack --pack-destination=./dist",
+ "test": "echo 'Tests for Midnight Network integration'"
+ },
+ "dependencies": {
+ "@midnight-ntwrk/compact-runtime": "^0.8.1",
+ "@midnight-ntwrk/ledger": "^4.0.0",
+ "@midnight-ntwrk/midnight-js-contracts": "2.0.2",
+ "@midnight-ntwrk/midnight-js-types": "2.0.2",
+ "@midnight-ntwrk/zswap": "4.0.0",
+ "@radix-ui/react-dialog": "^1.1.14",
+ "@radix-ui/react-label": "^2.1.7",
+ "@radix-ui/react-progress": "^1.1.7",
+ "@radix-ui/react-slot": "^1.2.3",
+ "class-variance-authority": "^0.7.1",
+ "clsx": "^2.1.1",
+ "fp-ts": "^2.16.1",
+ "lucide-react": "^0.523.0",
+ "pino": "^8.16.1",
+ "rxjs": "^7.8.1",
+ "semver": "^7.6.0",
+ "tailwind-merge": "^3.3.1"
+ },
+ "peerDependencies": {
+ "@midnight-ntwrk/dapp-connector-api": "^3.0.0",
+ "@midnight-ntwrk/midnight-js-fetch-zk-config-provider": "^2.0.2",
+ "@midnight-ntwrk/midnight-js-http-client-proof-provider": "^2.0.2",
+ "@midnight-ntwrk/midnight-js-indexer-public-data-provider": "^2.0.2",
+ "@midnight-ntwrk/midnight-js-level-private-state-provider": "^2.0.2",
+ "@midnight-ntwrk/midnight-js-network-id": "^2.0.2",
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ },
+ "devDependencies": {
+ "@meshsdk/configs": "*",
+ "@types/react": "^18.2.61",
+ "@types/react-dom": "^18.2.19",
+ "@types/ws": "^8.5.9",
+ "eslint": "^8.57.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "tsup": "^8.0.2",
+ "typescript": "^5.3.3"
+ },
+ "prettier": "@meshsdk/configs/prettier",
+ "publishConfig": {
+ "access": "public"
+ },
+ "license": "MIT",
+ "keywords": [
+ "midnight",
+ "midnight-network",
+ "blockchain",
+ "smart-contracts",
+ "dapp",
+ "web3",
+ "compact",
+ "meshjs",
+ "cardano",
+ "sdk"
+ ]
+}
diff --git a/packages/midnight-setup/src/common-types.ts b/packages/midnight-setup/src/common-types.ts
new file mode 100644
index 000000000..f3892bf83
--- /dev/null
+++ b/packages/midnight-setup/src/common-types.ts
@@ -0,0 +1,52 @@
+import type {
+ PrivateStateProvider,
+ ZKConfigProvider,
+ ProofProvider,
+ PublicDataProvider,
+ WalletProvider,
+ MidnightProvider
+} from "@midnight-ntwrk/midnight-js-types";
+
+// Private state identifier for the contract
+export const MidnightSetupPrivateStateId = "midnight-setup-private-state";
+export type MidnightSetupPrivateStateId = typeof MidnightSetupPrivateStateId;
+
+// Circuit keys type for proof provider
+export type TokenCircuitKeys = string;
+
+// Contract providers interface with proper types
+export interface MidnightSetupContractProviders {
+ privateStateProvider: PrivateStateProvider;
+ zkConfigProvider: ZKConfigProvider;
+ proofProvider: ProofProvider;
+ publicDataProvider: PublicDataProvider;
+ walletProvider: WalletProvider;
+ midnightProvider: MidnightProvider;
+}
+
+// Contract state types - using unknown for flexible state data
+export interface ContractStateData {
+ readonly address: string;
+ readonly data: unknown;
+ readonly blockHeight?: string;
+ readonly blockHash?: string;
+ readonly message?: string;
+ readonly error?: string;
+}
+
+export interface LedgerStateData {
+ readonly address: string;
+ readonly ledgerState?: {
+ readonly message: string | null;
+ };
+ readonly blockHeight?: string;
+ readonly blockHash?: string;
+ readonly rawData?: unknown;
+ readonly parseError?: string;
+ readonly error?: string;
+}
+
+export type DerivedMidnightSetupContractState = {
+ readonly protocolTVL: unknown[];
+ readonly projects: unknown[];
+};
diff --git a/packages/midnight-setup/src/index.ts b/packages/midnight-setup/src/index.ts
new file mode 100644
index 000000000..5c5f1e96d
--- /dev/null
+++ b/packages/midnight-setup/src/index.ts
@@ -0,0 +1,222 @@
+import { Observable } from "rxjs";
+import { ContractAddress } from "@midnight-ntwrk/compact-runtime";
+import { type Logger } from "pino";
+import { ledger, Contract } from "../contract-compiled/index.js";
+import { deployContract, findDeployedContract } from "@midnight-ntwrk/midnight-js-contracts";
+import * as utils from "./utils.js";
+import {
+ MidnightSetupContractProviders,
+ MidnightSetupPrivateStateId,
+ DerivedMidnightSetupContractState,
+ ContractStateData,
+ LedgerStateData,
+} from "./common-types.js";
+
+export interface DeployedMidnightSetupAPI {
+ readonly deployedContractAddress: ContractAddress;
+ readonly state: Observable;
+ getContractState: () => Promise;
+ getLedgerState: () => Promise;
+}
+/**
+ * NB: Declaring a class implements a given type, means it must contain all defined properties and methods, then take on other extra properties or class
+ */
+
+export class MidnightSetupAPI implements DeployedMidnightSetupAPI {
+ deployedContractAddress: string;
+ state: Observable;
+
+ private constructor(
+ private providers: MidnightSetupContractProviders,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public readonly allReadyDeployedContract: any,
+ private logger?: Logger
+ ) {
+ this.deployedContractAddress = allReadyDeployedContract.deployTxData.public.contractAddress;
+
+ // Real state observable
+ this.state = new Observable(subscriber => {
+ subscriber.next({
+ protocolTVL: [],
+ projects: [],
+ });
+ });
+ }
+
+ async getContractState(): Promise {
+ try {
+ this.logger?.info("Getting contract state...", { address: this.deployedContractAddress });
+
+ // Try to get contract state from public data provider
+ const contractState = await this.providers.publicDataProvider.queryContractState(this.deployedContractAddress);
+
+ if (contractState) {
+ this.logger?.info("Contract state retrieved successfully");
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const stateAny = contractState as any;
+ return {
+ address: this.deployedContractAddress,
+ data: contractState.data,
+ blockHeight: stateAny.blockHeight?.toString(),
+ blockHash: stateAny.blockHash?.toString(),
+ };
+ } else {
+ this.logger?.warn("No contract state found");
+ return {
+ address: this.deployedContractAddress,
+ data: null,
+ message: "No contract state found at this address"
+ };
+ }
+ } catch (error) {
+ this.logger?.error("Failed to get contract state", { error: error instanceof Error ? error.message : error });
+ return {
+ address: this.deployedContractAddress,
+ data: null,
+ error: error instanceof Error ? error.message : "Failed to get contract state"
+ };
+ }
+ }
+
+ async getLedgerState(): Promise {
+ try {
+ this.logger?.info("Getting ledger state...", { address: this.deployedContractAddress });
+
+ const contractState = await this.getContractState();
+
+ if (contractState.data) {
+ // Try to parse the ledger state
+ try {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const ledgerState = ledger(contractState.data as any);
+ this.logger?.info("Ledger state parsed successfully");
+ return {
+ address: this.deployedContractAddress,
+ ledgerState: {
+ message: ledgerState.message ? new TextDecoder().decode(ledgerState.message) : null,
+ },
+ blockHeight: contractState.blockHeight,
+ blockHash: contractState.blockHash,
+ };
+ } catch (parseError) {
+ this.logger?.warn("Failed to parse ledger state", { error: parseError });
+ return {
+ address: this.deployedContractAddress,
+ rawData: contractState.data,
+ parseError: parseError instanceof Error ? parseError.message : "Failed to parse ledger state"
+ };
+ }
+ } else {
+ return {
+ address: this.deployedContractAddress,
+ error: contractState.error || contractState.message
+ };
+ }
+ } catch (error) {
+ this.logger?.error("Failed to get ledger state", { error: error instanceof Error ? error.message : error });
+ return {
+ address: this.deployedContractAddress,
+ error: error instanceof Error ? error.message : "Failed to get ledger state"
+ };
+ }
+ }
+
+ static async deployMidnightSetupContract(
+ providers: MidnightSetupContractProviders,
+ logger?: Logger
+ ): Promise {
+ logger?.info("Deploying contract...");
+
+ try {
+ // Get or create initial private state
+ const initialPrivateState = await MidnightSetupAPI.getPrivateState(providers);
+
+ // Create contract instance with constructor arguments
+ const contractInstance = new Contract({});
+
+ // Real contract deployment using the wallet
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const deployedContract = await deployContract(
+ providers as any,
+ {
+ contract: contractInstance,
+ initialPrivateState: initialPrivateState,
+ privateStateId: MidnightSetupPrivateStateId,
+ }
+ );
+
+ logger?.info("Contract deployed successfully", {
+ address: deployedContract.deployTxData.public.contractAddress
+ });
+ return new MidnightSetupAPI(providers, deployedContract, logger);
+ } catch (error) {
+ logger?.error("Failed to deploy contract", {
+ error: error instanceof Error ? error.message : String(error),
+ stack: error instanceof Error ? error.stack : undefined
+ });
+ throw error;
+ }
+ }
+
+ static async joinMidnightSetupContract(
+ providers: MidnightSetupContractProviders,
+ contractAddress: string,
+ logger?: Logger
+ ): Promise {
+ logger?.info("Joining contract...", { contractAddress });
+
+ try {
+ // Get or create initial private state
+ const initialPrivateState = await MidnightSetupAPI.getPrivateState(providers);
+
+ // Create contract instance
+ const contractInstance = new Contract({});
+
+ // Real contract join using the wallet
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const existingContract = await findDeployedContract(
+ providers as any,
+ {
+ contract: contractInstance,
+ contractAddress: contractAddress,
+ privateStateId: MidnightSetupPrivateStateId,
+ initialPrivateState: initialPrivateState,
+ }
+ );
+
+ logger?.info("Successfully joined contract", {
+ address: existingContract.deployTxData.public.contractAddress
+ });
+ return new MidnightSetupAPI(providers, existingContract, logger);
+ } catch (error) {
+ logger?.error("Failed to join contract", {
+ error: error instanceof Error ? error.message : String(error),
+ contractAddress
+ });
+ throw error;
+ }
+ }
+
+ private static async getPrivateState(
+ providers: MidnightSetupContractProviders
+ ): Promise> {
+ try {
+ const existingPrivateState = await providers.privateStateProvider.get(
+ MidnightSetupPrivateStateId
+ );
+
+ // If no existing state, return empty object (the contract will initialize it)
+ return existingPrivateState ?? {};
+ } catch (error) {
+ console.warn("Error getting private state, returning empty object:", error);
+ return {};
+ }
+ }
+}
+
+export * as utils from "./utils.js";
+
+export * from "./common-types.js";
+
+// Re-export types for external use
+export type { ContractStateData, LedgerStateData } from "./common-types.js";
diff --git a/packages/midnight-setup/src/react.ts b/packages/midnight-setup/src/react.ts
new file mode 100644
index 000000000..410ffa27f
--- /dev/null
+++ b/packages/midnight-setup/src/react.ts
@@ -0,0 +1,23 @@
+// React hooks and providers for Midnight Network
+export { default as MidnightWalletProvider, MidnightWalletContext } from "./react/providers/MidnightWalletProvider";
+export type { MidnightWalletState, MidnightWalletContextType } from "./react/providers/MidnightWalletProvider";
+
+export { default as DeployedContractProvider } from "./react/providers/DeployedContractProvider";
+
+export { default as useMidnightWallet } from "./react/hooks/useMidnightWallet";
+
+// UI Components
+export { Badge } from "./react/components/badge";
+export { Button } from "./react/components/button";
+export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } from "./react/components/card";
+export { Dialog, DialogPortal, DialogOverlay, DialogTrigger, DialogClose, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription } from "./react/components/dialog";
+export { Input } from "./react/components/input";
+export { Label } from "./react/components/label";
+export { Progress } from "./react/components/progress";
+export { Textarea } from "./react/components/textarea";
+
+// Utils
+export * from "./react/common-types";
+export * from "./react/utils";
+export * from "./react/actions";
+
diff --git a/packages/midnight-setup/src/react/actions.ts b/packages/midnight-setup/src/react/actions.ts
new file mode 100644
index 000000000..ecd13a2c8
--- /dev/null
+++ b/packages/midnight-setup/src/react/actions.ts
@@ -0,0 +1,226 @@
+import { type ContractAddress } from "@midnight-ntwrk/compact-runtime";
+import {
+ concatMap,
+ filter,
+ firstValueFrom,
+ interval,
+ map,
+ of,
+ take,
+ tap,
+ throwError,
+ timeout,
+ catchError,
+} from "rxjs";
+import { pipe as fnPipe } from "fp-ts/function";
+import {
+ type DAppConnectorAPI,
+ type DAppConnectorWalletAPI,
+ type ServiceUriConfig,
+} from "@midnight-ntwrk/dapp-connector-api";
+import { levelPrivateStateProvider } from "@midnight-ntwrk/midnight-js-level-private-state-provider";
+import { FetchZkConfigProvider } from "@midnight-ntwrk/midnight-js-fetch-zk-config-provider";
+import { httpClientProofProvider } from "@midnight-ntwrk/midnight-js-http-client-proof-provider";
+import { indexerPublicDataProvider } from "@midnight-ntwrk/midnight-js-indexer-public-data-provider";
+import {
+ type BalancedTransaction,
+ type UnbalancedTransaction,
+ createBalancedTx,
+} from "@midnight-ntwrk/midnight-js-types";
+import {
+ type CoinInfo,
+ Transaction,
+ type TransactionId,
+} from "@midnight-ntwrk/ledger";
+import { Transaction as ZswapTransaction } from "@midnight-ntwrk/zswap";
+import * as semver from "semver";
+import {
+ getLedgerNetworkId,
+ getZswapNetworkId,
+} from "@midnight-ntwrk/midnight-js-network-id";
+import {
+ MidnightSetupAPI,
+ type MidnightSetupContractProviders,
+ type DeployedMidnightSetupAPI,
+ type TokenCircuitKeys,
+} from "../index";
+import type { WalletAndProvider } from "./common-types";
+import type { Logger } from "pino";
+
+const connectWallet = async (): Promise<{
+ wallet: DAppConnectorWalletAPI;
+ uris: ServiceUriConfig;
+}> => {
+ const COMPATIBLE_CONNECTOR_API_VERSION = "1.x";
+ return firstValueFrom(
+ fnPipe(
+ interval(100),
+ map(() => window.midnight?.mnLace),
+ tap((connectorAPI) => {
+ console.info(connectorAPI, "Check for wallet connector API");
+ }),
+ filter(
+ (connectorAPI): connectorAPI is DAppConnectorAPI => !!connectorAPI
+ ),
+ concatMap((connectorAPI) =>
+ semver.satisfies(
+ connectorAPI.apiVersion,
+ COMPATIBLE_CONNECTOR_API_VERSION
+ )
+ ? of(connectorAPI)
+ : throwError(() => {
+ console.error(
+ {
+ expected: COMPATIBLE_CONNECTOR_API_VERSION,
+ actual: connectorAPI.apiVersion,
+ },
+ "Incompatible version of wallet connector API"
+ );
+
+ return new Error(
+ `Incompatible version of Midnight Lace wallet found. Require '${COMPATIBLE_CONNECTOR_API_VERSION}', got '${connectorAPI.apiVersion}'.`
+ );
+ })
+ ),
+ tap((connectorAPI) => {
+ console.info(
+ connectorAPI,
+ "Compatible wallet connector API found. Connecting."
+ );
+ }),
+ take(1),
+ timeout({
+ first: 1_000,
+ with: () =>
+ throwError(() => {
+ console.error("Could not find wallet connector API");
+
+ return new Error(
+ "Could not find Midnight Lace wallet. Extension installed?"
+ );
+ }),
+ }),
+ concatMap(async (connectorAPI) => {
+ const isEnabled = await connectorAPI.isEnabled();
+
+ console.info(isEnabled, "Wallet connector API enabled status");
+
+ return connectorAPI;
+ }),
+ timeout({
+ first: 5_000,
+ with: () =>
+ throwError(() => {
+ console.error("Wallet connector API has failed to respond");
+
+ return new Error(
+ "Midnight Lace wallet has failed to respond. Extension enabled?"
+ );
+ }),
+ }),
+ concatMap(async (connectorAPI) => ({
+ walletConnectorAPI: await connectorAPI.enable(),
+ connectorAPI,
+ })),
+ catchError((error, apis) =>
+ error
+ ? throwError(() => {
+ console.error("Unable to enable connector API");
+ return new Error("Application is not authorized");
+ })
+ : apis
+ ),
+ concatMap(async ({ walletConnectorAPI, connectorAPI }) => {
+ const uris = await connectorAPI.serviceUriConfig();
+
+ console.info(
+ "Connected to wallet connector API and retrieved service configuration"
+ );
+
+ return { wallet: walletConnectorAPI, uris };
+ })
+ )
+ );
+};
+
+export const initialWalletAndProviders =
+ async (): Promise => {
+ const { wallet, uris } = await connectWallet();
+ const walletState = await wallet.state();
+
+ const providers = {
+ privateStateProvider: levelPrivateStateProvider({
+ privateStateStoreName: "midnight-setup-private-state",
+ }),
+ zkConfigProvider: new FetchZkConfigProvider(
+ window.location.origin,
+ fetch.bind(window)
+ ),
+ proofProvider: httpClientProofProvider(uris.proverServerUri),
+ publicDataProvider: indexerPublicDataProvider(
+ uris.indexerUri,
+ uris.indexerWsUri
+ ),
+ walletProvider: {
+ coinPublicKey: walletState.coinPublicKey,
+ encryptionPublicKey: walletState.encryptionPublicKey,
+ balanceTx(
+ tx: UnbalancedTransaction,
+ newCoins: CoinInfo[]
+ ): Promise {
+ return wallet
+ .balanceAndProveTransaction(
+ ZswapTransaction.deserialize(
+ tx.serialize(getLedgerNetworkId()),
+ getZswapNetworkId()
+ ),
+ newCoins
+ )
+ .then((zswapTx) =>
+ Transaction.deserialize(
+ zswapTx.serialize(getZswapNetworkId()),
+ getLedgerNetworkId()
+ )
+ )
+ .then(createBalancedTx)
+ .finally(() => {
+ console.log("balanceTxDone");
+ });
+ },
+ },
+ midnightProvider: {
+ submitTx(tx: BalancedTransaction): Promise {
+ return wallet.submitTransaction(tx);
+ },
+ },
+ };
+
+ return { wallet, uris, providers };
+ };
+
+export const resolve = async (
+ providers: MidnightSetupContractProviders,
+ logger: Logger,
+ contractAddress?: ContractAddress
+): Promise => {
+ let api;
+ if (contractAddress) {
+ api = await MidnightSetupAPI.joinMidnightSetupContract(
+ providers,
+ contractAddress
+ );
+ } else {
+ api = await MidnightSetupAPI.deployMidnightSetupContract(providers, logger);
+ }
+
+ return api;
+};
+
+export const calculateExpiryDate = (duration: number, creationDate: number) => {
+ const millisecondsPerHour = 1000 * 60 * 60 * 24;
+ const durationInMilliseconds = millisecondsPerHour * duration;
+ const expiryDate = creationDate + durationInMilliseconds;
+
+ const dateObject = new Date(expiryDate);
+ return dateObject.toLocaleDateString();
+};
diff --git a/packages/midnight-setup/src/react/common-types.ts b/packages/midnight-setup/src/react/common-types.ts
new file mode 100644
index 000000000..7ad765ebf
--- /dev/null
+++ b/packages/midnight-setup/src/react/common-types.ts
@@ -0,0 +1,22 @@
+import type { MidnightSetupContractProviders, DeployedMidnightSetupAPI } from "../index";
+import type { DAppConnectorWalletAPI, ServiceUriConfig } from "@midnight-ntwrk/dapp-connector-api";
+
+
+export interface WalletAndProvider{
+ readonly wallet: DAppConnectorWalletAPI,
+ readonly uris: ServiceUriConfig,
+ readonly providers: MidnightSetupContractProviders
+}
+
+export interface WalletAPI {
+ wallet: DAppConnectorWalletAPI;
+ coinPublicKey: string;
+ encryptionPublicKey: string;
+ uris: ServiceUriConfig;
+}
+
+
+export interface MidnightSetupDeployment{
+ status: "inprogress" | "deployed" | "failed",
+ api: DeployedMidnightSetupAPI;
+}
\ No newline at end of file
diff --git a/packages/midnight-setup/src/react/components/badge.tsx b/packages/midnight-setup/src/react/components/badge.tsx
new file mode 100644
index 000000000..0f7d665e1
--- /dev/null
+++ b/packages/midnight-setup/src/react/components/badge.tsx
@@ -0,0 +1,46 @@
+import * as React from "react"
+import { Slot } from "@radix-ui/react-slot"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "../utils"
+
+const badgeVariants = cva(
+ "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
+ {
+ variants: {
+ variant: {
+ default:
+ "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
+ secondary:
+ "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
+ destructive:
+ "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
+ outline:
+ "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+)
+
+function Badge({
+ className,
+ variant,
+ asChild = false,
+ ...props
+}: React.ComponentProps<"span"> &
+ VariantProps & { asChild?: boolean }) {
+ const Comp = asChild ? Slot : "span"
+
+ return (
+
+ )
+}
+
+export { Badge, badgeVariants }
diff --git a/packages/midnight-setup/src/react/components/button.tsx b/packages/midnight-setup/src/react/components/button.tsx
new file mode 100644
index 000000000..6739b80b7
--- /dev/null
+++ b/packages/midnight-setup/src/react/components/button.tsx
@@ -0,0 +1,59 @@
+import * as React from "react"
+import { Slot } from "@radix-ui/react-slot"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "../utils"
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ {
+ variants: {
+ variant: {
+ default:
+ "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
+ destructive:
+ "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
+ outline:
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
+ secondary:
+ "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
+ ghost:
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
+ icon: "size-9",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+function Button({
+ className,
+ variant,
+ size,
+ asChild = false,
+ ...props
+}: React.ComponentProps<"button"> &
+ VariantProps & {
+ asChild?: boolean
+ }) {
+ const Comp = asChild ? Slot : "button"
+
+ return (
+
+ )
+}
+
+export { Button, buttonVariants }
diff --git a/packages/midnight-setup/src/react/components/card.tsx b/packages/midnight-setup/src/react/components/card.tsx
new file mode 100644
index 000000000..fa6134e40
--- /dev/null
+++ b/packages/midnight-setup/src/react/components/card.tsx
@@ -0,0 +1,92 @@
+import * as React from "react"
+
+import { cn } from "../utils"
+
+function Card({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardAction({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardContent({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+export {
+ Card,
+ CardHeader,
+ CardFooter,
+ CardTitle,
+ CardAction,
+ CardDescription,
+ CardContent,
+}
diff --git a/packages/midnight-setup/src/react/components/dialog.tsx b/packages/midnight-setup/src/react/components/dialog.tsx
new file mode 100644
index 000000000..8805130ae
--- /dev/null
+++ b/packages/midnight-setup/src/react/components/dialog.tsx
@@ -0,0 +1,141 @@
+import * as React from "react"
+import * as DialogPrimitive from "@radix-ui/react-dialog"
+import { XIcon } from "lucide-react"
+
+import { cn } from "../utils"
+
+function Dialog({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogTrigger({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogPortal({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogClose({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogOverlay({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DialogContent({
+ className,
+ children,
+ showCloseButton = true,
+ ...props
+}: React.ComponentProps & {
+ showCloseButton?: boolean
+}) {
+ return (
+
+
+
+ {children}
+ {showCloseButton && (
+
+
+ Close
+
+ )}
+
+
+ )
+}
+
+function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function DialogTitle({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DialogDescription({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogOverlay,
+ DialogPortal,
+ DialogTitle,
+ DialogTrigger,
+}
diff --git a/packages/midnight-setup/src/react/components/input.tsx b/packages/midnight-setup/src/react/components/input.tsx
new file mode 100644
index 000000000..5cfce2051
--- /dev/null
+++ b/packages/midnight-setup/src/react/components/input.tsx
@@ -0,0 +1,21 @@
+import * as React from "react"
+
+import { cn } from "../utils"
+
+function Input({ className, type, ...props }: React.ComponentProps<"input">) {
+ return (
+
+ )
+}
+
+export { Input }
diff --git a/packages/midnight-setup/src/react/components/label.tsx b/packages/midnight-setup/src/react/components/label.tsx
new file mode 100644
index 000000000..6717e34ef
--- /dev/null
+++ b/packages/midnight-setup/src/react/components/label.tsx
@@ -0,0 +1,22 @@
+import * as React from "react"
+import * as LabelPrimitive from "@radix-ui/react-label"
+
+import { cn } from "../utils"
+
+function Label({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export { Label }
diff --git a/packages/midnight-setup/src/react/components/progress.tsx b/packages/midnight-setup/src/react/components/progress.tsx
new file mode 100644
index 000000000..b622ce8ab
--- /dev/null
+++ b/packages/midnight-setup/src/react/components/progress.tsx
@@ -0,0 +1,31 @@
+"use client"
+
+import * as React from "react"
+import * as ProgressPrimitive from "@radix-ui/react-progress"
+
+import { cn } from "../utils"
+
+function Progress({
+ className,
+ value,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+export { Progress }
diff --git a/packages/midnight-setup/src/react/components/textarea.tsx b/packages/midnight-setup/src/react/components/textarea.tsx
new file mode 100644
index 000000000..9353ed364
--- /dev/null
+++ b/packages/midnight-setup/src/react/components/textarea.tsx
@@ -0,0 +1,18 @@
+import * as React from "react"
+
+import { cn } from "../utils"
+
+function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
+ return (
+
+ )
+}
+
+export { Textarea }
diff --git a/packages/midnight-setup/src/react/hooks/useMidnightWallet.tsx b/packages/midnight-setup/src/react/hooks/useMidnightWallet.tsx
new file mode 100644
index 000000000..cf781da83
--- /dev/null
+++ b/packages/midnight-setup/src/react/hooks/useMidnightWallet.tsx
@@ -0,0 +1,12 @@
+import { MidnightWalletContext } from '../providers/MidnightWalletProvider'
+import { useContext } from 'react'
+
+export const useMidnightWallet = () => {
+ const context = useContext(MidnightWalletContext)
+ if(!context){
+ return;
+ }
+ return context;
+}
+
+export default useMidnightWallet
\ No newline at end of file
diff --git a/packages/midnight-setup/src/react/polyfills.ts b/packages/midnight-setup/src/react/polyfills.ts
new file mode 100644
index 000000000..ad66ba461
--- /dev/null
+++ b/packages/midnight-setup/src/react/polyfills.ts
@@ -0,0 +1,10 @@
+// src/polyfills.ts - Create this file
+import { Buffer } from 'buffer'
+
+// Make Buffer available globally
+window.Buffer = Buffer
+window.global = window.global || window
+window.process = window.process || { env: {} }
+
+// Export for direct imports
+export { Buffer }
\ No newline at end of file
diff --git a/packages/midnight-setup/src/react/providers/DeployedContractProvider.tsx b/packages/midnight-setup/src/react/providers/DeployedContractProvider.tsx
new file mode 100644
index 000000000..69b18bd0c
--- /dev/null
+++ b/packages/midnight-setup/src/react/providers/DeployedContractProvider.tsx
@@ -0,0 +1,160 @@
+import useMidnightWallet from "../hooks/useMidnightWallet";
+import { MidnightSetupAPI, type DeployedMidnightSetupAPI } from "../../index";
+import type { Logger } from "pino";
+import {
+ createContext,
+ useCallback,
+ useContext,
+ useState,
+ type PropsWithChildren,
+} from "react";
+
+export interface DeploymentProvider {
+ readonly isJoining: boolean;
+ readonly isDeploying: boolean;
+ readonly error: string | null;
+ readonly hasJoined: boolean;
+ readonly hasDeployed: boolean;
+ readonly midnightSetupApi: DeployedMidnightSetupAPI | undefined;
+ readonly deployedContractAddress: string | undefined;
+ onJoinContract: (address: string) => Promise;
+ onDeployContract: () => Promise;
+ clearError: () => void;
+}
+
+export const DeployedContractContext = createContext(null);
+
+interface DeployedContractProviderProps extends PropsWithChildren {
+ logger?: Logger;
+}
+
+const DeployedContractProvider = ({
+ children,
+ logger
+}: DeployedContractProviderProps) => {
+
+ const [midnightSetupApi, setMidnightSetupApi] = useState(undefined);
+ const [isJoining, setIsJoining] = useState(false);
+ const [isDeploying, setIsDeploying] = useState(false);
+ const [error, setError] = useState(null);
+ const [hasJoined, setHasJoined] = useState(false);
+ const [hasDeployed, setHasDeployed] = useState(false);
+ const [deployedContractAddress, setDeployedContractAddress] = useState(undefined);
+
+ // Use the custom hook instead of useContext directly
+ const walletContext = useMidnightWallet();
+
+ const onJoinContract = useCallback(async (address: string) => {
+ // Prevent multiple simultaneous joins
+ if (isJoining || hasJoined || isDeploying || hasDeployed) return;
+
+ // Validate requirements
+ if (!walletContext?.walletState.hasConnected || !walletContext?.walletState.providers) {
+ setError("Wallet must be connected before joining contract");
+ return;
+ }
+
+ if (!address) {
+ setError("Contract address is required");
+ return;
+ }
+
+ setIsJoining(true);
+ setError(null);
+
+ try {
+ const deployedAPI = await MidnightSetupAPI.joinMidnightSetupContract(
+ walletContext.walletState.providers,
+ address,
+ logger
+ );
+
+ setMidnightSetupApi(deployedAPI);
+ setHasJoined(true);
+ setDeployedContractAddress(deployedAPI.deployedContractAddress);
+ logger?.info("Successfully joined contract", { contractAddress: address });
+
+ } catch (error) {
+ const errMsg = error instanceof Error
+ ? error.message
+ : `Failed to join contract at ${address}`;
+ setError(errMsg);
+ logger?.error("Failed to join contract", { error: errMsg, contractAddress: address });
+ } finally {
+ setIsJoining(false);
+ }
+ }, [isJoining, hasJoined, isDeploying, hasDeployed, walletContext?.walletState.hasConnected, walletContext?.walletState.providers, logger]);
+
+ const onDeployContract = useCallback(async () => {
+ // Prevent multiple simultaneous operations
+ if (isDeploying || hasDeployed || isJoining || hasJoined) return;
+
+ // Validate requirements
+ if (!walletContext?.walletState.hasConnected || !walletContext?.walletState.providers) {
+ setError("Wallet must be connected before deploying contract");
+ return;
+ }
+
+ setIsDeploying(true);
+ setError(null);
+
+ try {
+ const deployedAPI = await MidnightSetupAPI.deployMidnightSetupContract(
+ walletContext.walletState.providers,
+ logger
+ );
+
+ setMidnightSetupApi(deployedAPI);
+ setHasDeployed(true);
+ setDeployedContractAddress(deployedAPI.deployedContractAddress);
+ logger?.info("Successfully deployed new contract", {
+ contractAddress: deployedAPI.deployedContractAddress
+ });
+
+ } catch (error) {
+ const errMsg = error instanceof Error
+ ? error.message
+ : "Failed to deploy new contract";
+ setError(errMsg);
+ logger?.error("Failed to deploy contract", { error: errMsg });
+ } finally {
+ setIsDeploying(false);
+ }
+ }, [isDeploying, hasDeployed, isJoining, hasJoined, walletContext?.walletState.hasConnected, walletContext?.walletState.providers, logger]);
+
+ const clearError = useCallback(() => {
+ setError(null);
+ }, []);
+
+ const contextValue: DeploymentProvider = {
+ isJoining,
+ isDeploying,
+ hasJoined,
+ hasDeployed,
+ error,
+ midnightSetupApi,
+ deployedContractAddress,
+ onJoinContract,
+ onDeployContract,
+ clearError,
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+// Custom hook for consuming the context
+export const useDeployedContract = (): DeploymentProvider => {
+ const context = useContext(DeployedContractContext);
+
+ if (!context) {
+ throw new Error("useDeployedContract must be used within a DeployedContractProvider");
+ }
+
+ return context;
+};
+
+export default DeployedContractProvider;
\ No newline at end of file
diff --git a/packages/midnight-setup/src/react/providers/MidnightWalletProvider.tsx b/packages/midnight-setup/src/react/providers/MidnightWalletProvider.tsx
new file mode 100644
index 000000000..ab0275b0b
--- /dev/null
+++ b/packages/midnight-setup/src/react/providers/MidnightWalletProvider.tsx
@@ -0,0 +1,173 @@
+import { initialWalletAndProviders } from "../actions";
+import type { WalletAPI } from "../common-types";
+import type { MidnightSetupContractProviders } from "../../common-types";
+import type { Logger } from "pino";
+import {
+ createContext,
+ useReducer,
+ useCallback,
+ type PropsWithChildren,
+} from "react";
+
+export interface MidnightWalletState {
+ readonly address: string | undefined;
+ readonly isConnecting: boolean;
+ readonly coinPublicKey: string | undefined;
+ readonly providers: MidnightSetupContractProviders | undefined;
+ readonly walletAPI: WalletAPI | undefined;
+ readonly hasConnected: boolean;
+ readonly error: string | null;
+}
+
+export interface MidnightWalletContextType {
+ walletState: MidnightWalletState;
+ connectToWalletAndInitializeProviders: () => Promise;
+ disconnect: () => void;
+ clearError: () => void;
+}
+
+// Initial state
+const initialState: MidnightWalletState = {
+ address: undefined,
+ isConnecting: false,
+ coinPublicKey: undefined,
+ providers: undefined,
+ walletAPI: undefined,
+ hasConnected: false,
+ error: null,
+};
+
+// Action types
+type WalletAction =
+ | { type: "CONNECT_START" }
+ | {
+ type: "CONNECT_SUCCESS";
+ payload: Omit<
+ MidnightWalletState,
+ "isConnecting" | "hasConnected" | "error"
+ >;
+ }
+ | { type: "CONNECT_ERROR"; payload: string }
+ | { type: "DISCONNECT" }
+ | { type: "CLEAR_ERROR" };
+
+// Reducer
+function walletReducer(
+ state: MidnightWalletState,
+ action: WalletAction
+): MidnightWalletState {
+ switch (action.type) {
+ case "CONNECT_START":
+ return {
+ ...state,
+ isConnecting: true,
+ error: null,
+ };
+ case "CONNECT_SUCCESS":
+ return {
+ ...state,
+ ...action.payload,
+ isConnecting: false,
+ hasConnected: true,
+ error: null,
+ };
+ case "CONNECT_ERROR":
+ return {
+ ...state,
+ isConnecting: false,
+ error: action.payload,
+ };
+ case "DISCONNECT":
+ return {
+ ...initialState,
+ hasConnected: false,
+ };
+ case "CLEAR_ERROR":
+ return {
+ ...state,
+ error: null,
+ };
+ default:
+ return state;
+ }
+}
+
+// Context
+export const MidnightWalletContext =
+ createContext(null);
+
+// Provider Props
+interface MidnightWalletProviderProps extends PropsWithChildren {
+ logger?: Logger;
+}
+
+const MidnightWalletProvider = ({
+ children,
+ logger,
+}: MidnightWalletProviderProps) => {
+ const [walletState, dispatch] = useReducer(walletReducer, initialState);
+
+ const connectToWalletAndInitializeProviders = useCallback(async () => {
+ if (walletState.isConnecting) return; // Prevent multiple simultaneous connections
+
+ dispatch({ type: "CONNECT_START" });
+
+ try {
+ const { wallet, uris, providers } = await initialWalletAndProviders();
+
+ if (!wallet) {
+ throw new Error("Failed to initialize wallet");
+ }
+
+ const walletStateData = await wallet.state();
+
+ dispatch({
+ type: "CONNECT_SUCCESS",
+ payload: {
+ address: walletStateData.address,
+ coinPublicKey: walletStateData.coinPublicKey,
+ providers,
+ walletAPI: {
+ wallet,
+ uris,
+ coinPublicKey: walletStateData.coinPublicKey,
+ encryptionPublicKey: walletStateData.encryptionPublicKey,
+ },
+ },
+ });
+
+ logger?.info("Wallet connected successfully", {
+ address: walletStateData.address,
+ });
+ } catch (error) {
+ const errorMessage =
+ error instanceof Error ? error.message : "Failed to initialize wallet";
+ dispatch({ type: "CONNECT_ERROR", payload: errorMessage });
+ logger?.error("Wallet connection failed", { error: errorMessage });
+ }
+ }, [walletState.isConnecting, logger]);
+
+ const disconnect = useCallback(() => {
+ dispatch({ type: "DISCONNECT" });
+ logger?.info("Wallet disconnected");
+ }, [logger]);
+
+ const clearError = useCallback(() => {
+ dispatch({ type: "CLEAR_ERROR" });
+ }, []);
+
+ const contextValue: MidnightWalletContextType = {
+ walletState,
+ connectToWalletAndInitializeProviders,
+ disconnect,
+ clearError,
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export default MidnightWalletProvider;
diff --git a/packages/midnight-setup/src/react/styles.css b/packages/midnight-setup/src/react/styles.css
new file mode 100644
index 000000000..5a7873abc
--- /dev/null
+++ b/packages/midnight-setup/src/react/styles.css
@@ -0,0 +1,2 @@
+@import "tailwindcss";
+@import "tw-animate-css";
diff --git a/packages/midnight-setup/src/react/utils.ts b/packages/midnight-setup/src/react/utils.ts
new file mode 100644
index 000000000..bd0c391dd
--- /dev/null
+++ b/packages/midnight-setup/src/react/utils.ts
@@ -0,0 +1,6 @@
+import { clsx, type ClassValue } from "clsx"
+import { twMerge } from "tailwind-merge"
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs))
+}
diff --git a/packages/midnight-setup/src/utils.ts b/packages/midnight-setup/src/utils.ts
new file mode 100644
index 000000000..e81ba00cb
--- /dev/null
+++ b/packages/midnight-setup/src/utils.ts
@@ -0,0 +1,23 @@
+import { Logger } from "pino";
+
+// Simple utility functions for proof server connection
+export const randomNonceBytes = (length: number, logger?: Logger): Uint8Array => {
+ const newBytes = new Uint8Array(length);
+ crypto.getRandomValues(newBytes);
+ logger?.info("Random nonce bytes generated");
+ return newBytes;
+}
+
+export function hexStringToUint8Array(hexStr: string): Uint8Array {
+ // Simple hex to Uint8Array conversion
+ const hex = hexStr.replace(/^0x/, '');
+ const bytes = new Uint8Array(hex.length / 2);
+
+ for (let i = 0; i < hex.length; i += 2) {
+ bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
+ }
+
+ return bytes;
+}
+
+export default { randomNonceBytes, hexStringToUint8Array };
\ No newline at end of file
diff --git a/packages/midnight-setup/tsconfig.json b/packages/midnight-setup/tsconfig.json
new file mode 100644
index 000000000..36e3eea69
--- /dev/null
+++ b/packages/midnight-setup/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "extends": "@meshsdk/configs/typescript/base.json",
+ "compilerOptions": {
+ "outDir": "./dist",
+ "rootDir": "./src",
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "module": "ES2022",
+ "target": "ES2022",
+ "lib": ["ES2022", "DOM"],
+ "moduleResolution": "node",
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "resolveJsonModule": true,
+ "allowSyntheticDefaultImports": true,
+ "jsx": "react-jsx"
+ },
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
+}
+
diff --git a/packages/midnight-setup/tsup.config.ts b/packages/midnight-setup/tsup.config.ts
new file mode 100644
index 000000000..e66679765
--- /dev/null
+++ b/packages/midnight-setup/tsup.config.ts
@@ -0,0 +1,41 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: ["src/index.ts", "src/react.ts"],
+ format: ["esm", "cjs"],
+ dts: true,
+ splitting: false,
+ sourcemap: true,
+ clean: true,
+ treeshake: true,
+ cjsInterop: true,
+ external: [
+ "@midnight-ntwrk/compact-runtime",
+ "@midnight-ntwrk/ledger",
+ "@midnight-ntwrk/midnight-js-contracts",
+ "@midnight-ntwrk/midnight-js-types",
+ "@midnight-ntwrk/midnight-js-network-id",
+ "@midnight-ntwrk/zswap",
+ "@midnight-ntwrk/dapp-connector-api",
+ "@midnight-ntwrk/midnight-js-fetch-zk-config-provider",
+ "@midnight-ntwrk/midnight-js-http-client-proof-provider",
+ "@midnight-ntwrk/midnight-js-indexer-public-data-provider",
+ "@midnight-ntwrk/midnight-js-level-private-state-provider",
+ "fp-ts",
+ "pino",
+ "rxjs",
+ "semver",
+ "react",
+ "react-dom",
+ "react/jsx-runtime",
+ "@radix-ui/react-dialog",
+ "@radix-ui/react-label",
+ "@radix-ui/react-progress",
+ "@radix-ui/react-slot",
+ "lucide-react",
+ "class-variance-authority",
+ "clsx",
+ "tailwind-merge"
+ ],
+});
+
diff --git a/packages/midnight-setup/ui/.gitignore b/packages/midnight-setup/ui/.gitignore
new file mode 100644
index 000000000..fc5ae9f0c
--- /dev/null
+++ b/packages/midnight-setup/ui/.gitignore
@@ -0,0 +1,25 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+.vercel
diff --git a/packages/midnight-setup/ui/components.json b/packages/midnight-setup/ui/components.json
new file mode 100644
index 000000000..73afbdbcc
--- /dev/null
+++ b/packages/midnight-setup/ui/components.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "new-york",
+ "rsc": false,
+ "tsx": true,
+ "tailwind": {
+ "config": "",
+ "css": "src/index.css",
+ "baseColor": "neutral",
+ "cssVariables": true,
+ "prefix": ""
+ },
+ "aliases": {
+ "components": "@/components",
+ "utils": "@/lib/utils",
+ "ui": "@/components/ui",
+ "lib": "@/lib",
+ "hooks": "@/hooks"
+ },
+ "iconLibrary": "lucide"
+}
\ No newline at end of file
diff --git a/packages/midnight-setup/ui/eslint.config.js b/packages/midnight-setup/ui/eslint.config.js
new file mode 100644
index 000000000..d94e7deb7
--- /dev/null
+++ b/packages/midnight-setup/ui/eslint.config.js
@@ -0,0 +1,23 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import reactHooks from 'eslint-plugin-react-hooks'
+import reactRefresh from 'eslint-plugin-react-refresh'
+import tseslint from 'typescript-eslint'
+import { globalIgnores } from 'eslint/config'
+
+export default tseslint.config([
+ globalIgnores(['dist']),
+ {
+ files: ['**/*.{ts,tsx}'],
+ extends: [
+ js.configs.recommended,
+ tseslint.configs.recommended,
+ reactHooks.configs['recommended-latest'],
+ reactRefresh.configs.vite,
+ ],
+ languageOptions: {
+ ecmaVersion: 2020,
+ globals: globals.browser,
+ },
+ },
+])
diff --git a/packages/midnight-setup/ui/index.html b/packages/midnight-setup/ui/index.html
new file mode 100644
index 000000000..54c8470f9
--- /dev/null
+++ b/packages/midnight-setup/ui/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+ Midnight Setup | Powered by MeshJS
+
+
+
+
+
+
diff --git a/packages/midnight-setup/ui/package.json b/packages/midnight-setup/ui/package.json
new file mode 100644
index 000000000..7c5dd5dd7
--- /dev/null
+++ b/packages/midnight-setup/ui/package.json
@@ -0,0 +1,72 @@
+{
+ "name": "midnight-setup-ui",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "start": "http-server --port 0 ./dist",
+ "build": "tsc && vite build --mode testnet && cp public/mesh-logo.svg dist/mesh-logo.svg",
+ "lint": "eslint .",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@meshsdk/midnight-setup": "workspace:*",
+ "@midnight-setup/midnight-setup-contract": "workspace:*",
+ "@radix-ui/react-dialog": "^1.1.14",
+ "@radix-ui/react-label": "^2.1.7",
+ "@radix-ui/react-progress": "^1.1.7",
+ "@radix-ui/react-slot": "^1.2.3",
+ "@tailwindcss/vite": "^4.1.11",
+ "badge": "^1.0.3",
+ "button": "^1.1.1",
+ "card": "^2.5.4",
+ "class-variance-authority": "^0.7.1",
+ "clsx": "^2.1.1",
+ "dialog": "^0.3.1",
+ "http-server": "^14.1.1",
+ "init": "^0.1.2",
+ "input": "^1.0.1",
+ "label": "^0.2.2",
+ "lucide-react": "^0.523.0",
+ "progress": "^2.0.3",
+ "react": "^19.1.0",
+ "react-dom": "^19.1.0",
+ "react-hot-toast": "^2.5.2",
+ "shadcn": "^2.7.0",
+ "tailwind-merge": "^3.3.1",
+ "tailwindcss": "^4.1.11",
+ "textarea": "^0.3.0",
+ "uuid": "^11.1.0"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.29.0",
+ "@originjs/vite-plugin-commonjs": "^1.0.3",
+ "@types/node": "^24.0.4",
+ "@types/progress": "^2",
+ "@types/react": "^19.1.8",
+ "@types/react-dom": "^19.1.6",
+ "@vitejs/plugin-react": "^4.5.2",
+ "assert": "^2.0.0",
+ "browserify-fs": "^1.0.0",
+ "buffer": "^6.0.3",
+ "crypto-browserify": "^3.12.0",
+ "eslint": "^9.29.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
+ "eslint-plugin-react-refresh": "^0.4.20",
+ "globals": "^16.2.0",
+ "https-browserify": "^1.0.0",
+ "os-browserify": "^0.3.0",
+ "process": "^0.11.10",
+ "stream-browserify": "^3.0.0",
+ "stream-http": "^3.2.0",
+ "tw-animate-css": "^1.3.4",
+ "typescript": "~5.8.3",
+ "typescript-eslint": "^8.34.1",
+ "url": "^0.11.0",
+ "util": "^0.12.5",
+ "vite": "^7.0.0",
+ "vite-plugin-top-level-await": "^1.5.0",
+ "vite-plugin-wasm": "^3.4.1"
+ }
+}
diff --git a/packages/midnight-setup/ui/public/mesh-logo.svg b/packages/midnight-setup/ui/public/mesh-logo.svg
new file mode 100644
index 000000000..5c4ba0ae5
--- /dev/null
+++ b/packages/midnight-setup/ui/public/mesh-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/midnight-setup/ui/src/App.tsx b/packages/midnight-setup/ui/src/App.tsx
new file mode 100644
index 000000000..0be8f4993
--- /dev/null
+++ b/packages/midnight-setup/ui/src/App.tsx
@@ -0,0 +1,410 @@
+import { useMidnightWallet } from "./hookes/useMidnightWallet";
+import { useDeployedContract } from "./providers/DeployedContractProvider";
+import { Button } from "./components/ui/button";
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./components/ui/card";
+import { Input } from "./components/ui/input";
+import { Label } from "./components/ui/label";
+import { Badge } from "./components/ui/badge";
+import { Wallet, Loader2, CheckCircle, AlertCircle, Database, RefreshCw } from "lucide-react";
+import { useState } from "react";
+import type { ContractStateData, LedgerStateData } from "@meshsdk/midnight-setup";
+
+// Helper to safely stringify unknown data
+const safeStringify = (data: unknown): string => {
+ try {
+ return JSON.stringify(data, null, 2);
+ } catch {
+ return "Unable to display data";
+ }
+};
+
+function App() {
+ const walletContext = useMidnightWallet();
+ const contractContext = useDeployedContract();
+ const [contractAddress, setContractAddress] = useState("");
+ const [contractState, setContractState] = useState(null);
+ const [ledgerState, setLedgerState] = useState(null);
+ const [isLoadingState, setIsLoadingState] = useState(false);
+
+ const handleJoinContract = async () => {
+ if (contractAddress.trim()) {
+ await contractContext.onJoinContract(contractAddress.trim());
+ }
+ };
+
+ const handleDeployContract = async () => {
+ await contractContext.onDeployContract();
+ };
+
+ const handleGetContractState = async () => {
+ if (!contractContext.midnightSetupApi) return;
+
+ setIsLoadingState(true);
+ try {
+ const state = await contractContext.midnightSetupApi.getContractState();
+ setContractState(state);
+ } catch (error) {
+ console.error("Failed to get contract state:", error);
+ } finally {
+ setIsLoadingState(false);
+ }
+ };
+
+ const handleGetLedgerState = async () => {
+ if (!contractContext.midnightSetupApi) return;
+
+ setIsLoadingState(true);
+ try {
+ const state = await contractContext.midnightSetupApi.getLedgerState();
+ setLedgerState(state);
+ } catch (error) {
+ console.error("Failed to get ledger state:", error);
+ } finally {
+ setIsLoadingState(false);
+ }
+ };
+
+ return (
+
+
+
+
+ Midnight Setup
+
+
+ Connect your wallet, deploy or join contracts, view contract and ledger states, check your API, access your contract address and functions — all in one place. Modify as you like and just build!
+
+
+
+ {/* Wallet Connection Section */}
+
+
+
+
+ Wallet Connection
+
+
+ Connect to your Midnight wallet to get started
+
+
+
+ {walletContext?.walletState.hasConnected ? (
+
+
+
+
+ Connected: {walletContext.walletState.address?.slice(0, 6)}...
+ {walletContext.walletState.address?.slice(-4)}
+
+
+
+
+ Disconnect
+
+
+ ) : (
+
+
+
+ Wallet not connected
+
+
+
+ {walletContext?.walletState.isConnecting ? (
+ <>
+
+ Connecting...
+ >
+ ) : (
+ "Connect Wallet"
+ )}
+
+
+ )}
+
+ {walletContext?.walletState.error && (
+
+
{walletContext.walletState.error}
+
+ Clear Error
+
+
+ )}
+
+
+
+ {/* Contract Operations Section */}
+ {walletContext?.walletState.hasConnected && (
+
+
+ Contract Operations
+
+ Deploy a new contract or join an existing one
+
+
+
+ {/* Deploy Contract */}
+
+
Deploy New Contract
+
+
+ {contractContext.isDeploying ? (
+ <>
+
+ Deploying...
+ >
+ ) : (
+ "Deploy Contract"
+ )}
+
+ {contractContext.hasDeployed && (
+
+
+ Contract deployed at: {contractContext.deployedContractAddress}
+
+ )}
+
+
+
+ {/* Join Contract */}
+
+
Join Existing Contract
+
+
+ Contract Address
+ setContractAddress(e.target.value)}
+ disabled={contractContext.isJoining}
+ />
+
+
+ {contractContext.isJoining ? (
+ <>
+
+ Joining...
+ >
+ ) : (
+ "Join Contract"
+ )}
+
+
+ {contractContext.hasJoined && (
+
+
+ Successfully joined contract at: {contractContext.deployedContractAddress}
+
+ )}
+
+
+ {/* Error Display */}
+ {contractContext.error && (
+
+
{contractContext.error}
+
+ Clear Error
+
+
+ )}
+
+ {/* Contract Status */}
+ {(contractContext.hasDeployed || contractContext.hasJoined) && (
+
+
Contract Status
+
+
Status: {contractContext.hasDeployed ? "Deployed" : "Joined"}
+
Address: {contractContext.deployedContractAddress}
+
API Available: {contractContext.midnightSetupApi ? "Yes" : "No"}
+
+
+ )}
+
+
+ )}
+
+ {/* Contract State Reading Section */}
+ {(contractContext.hasDeployed || contractContext.hasJoined) && (
+
+
+
+
+ Contract State Reader
+
+
+ Read and display the current state of the deployed contract
+
+
+
+
+
+ {isLoadingState ? (
+ <>
+
+ Loading...
+ >
+ ) : (
+ <>
+
+ Get Contract State
+ >
+ )}
+
+
+ {isLoadingState ? (
+ <>
+
+ Loading...
+ >
+ ) : (
+ <>
+
+ Get Ledger State
+ >
+ )}
+
+
+
+ {/* Contract State Display */}
+ {contractState && (
+
+
Contract State
+
+
Address: {contractState.address}
+ {contractState.blockHeight && (
+
Block Height: {contractState.blockHeight}
+ )}
+ {contractState.blockHash && (
+
Block Hash: {contractState.blockHash}
+ )}
+ {contractState.error && (
+
Error: {contractState.error}
+ )}
+ {contractState.message && (
+
Message: {contractState.message}
+ )}
+ {contractState.data !== null && contractState.data !== undefined ? (
+
+
Raw Data:
+
+ {safeStringify(contractState.data)}
+
+
+ ) : null}
+
+
+ )}
+
+ {/* Ledger State Display */}
+ {ledgerState && (
+
+
Ledger State
+
+
Address: {ledgerState.address}
+ {ledgerState.blockHeight && (
+
Block Height: {ledgerState.blockHeight}
+ )}
+ {ledgerState.blockHash && (
+
Block Hash: {ledgerState.blockHash}
+ )}
+ {ledgerState.error && (
+
Error: {ledgerState.error}
+ )}
+ {ledgerState.parseError && (
+
Parse Error: {ledgerState.parseError}
+ )}
+ {ledgerState.ledgerState && (
+
+ {ledgerState.ledgerState.message && (
+
Message: {ledgerState.ledgerState.message}
+ )}
+
+
Parsed Data:
+
+ {JSON.stringify(ledgerState.ledgerState, null, 2)}
+
+
+
+ )}
+ {ledgerState.rawData !== null && ledgerState.rawData !== undefined ? (
+
+
Raw Data (could not parse):
+
+ {safeStringify(ledgerState.rawData)}
+
+
+ ) : null}
+
+
+ )}
+
+
+ )}
+
+ {/* Footer Banner - Powered by MeshJS Team */}
+
+
+
+
+ Built with ❤️ on Midnight Network
+
+
+
+
+
+ );
+}
+
+export default App;
\ No newline at end of file
diff --git a/packages/midnight-setup/ui/src/components/ui/badge.tsx b/packages/midnight-setup/ui/src/components/ui/badge.tsx
new file mode 100644
index 000000000..02054139a
--- /dev/null
+++ b/packages/midnight-setup/ui/src/components/ui/badge.tsx
@@ -0,0 +1,46 @@
+import * as React from "react"
+import { Slot } from "@radix-ui/react-slot"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "@/lib/utils"
+
+const badgeVariants = cva(
+ "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
+ {
+ variants: {
+ variant: {
+ default:
+ "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
+ secondary:
+ "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
+ destructive:
+ "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
+ outline:
+ "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+)
+
+function Badge({
+ className,
+ variant,
+ asChild = false,
+ ...props
+}: React.ComponentProps<"span"> &
+ VariantProps & { asChild?: boolean }) {
+ const Comp = asChild ? Slot : "span"
+
+ return (
+
+ )
+}
+
+export { Badge, badgeVariants }
diff --git a/packages/midnight-setup/ui/src/components/ui/button.tsx b/packages/midnight-setup/ui/src/components/ui/button.tsx
new file mode 100644
index 000000000..a2df8dce6
--- /dev/null
+++ b/packages/midnight-setup/ui/src/components/ui/button.tsx
@@ -0,0 +1,59 @@
+import * as React from "react"
+import { Slot } from "@radix-ui/react-slot"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "@/lib/utils"
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ {
+ variants: {
+ variant: {
+ default:
+ "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
+ destructive:
+ "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
+ outline:
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
+ secondary:
+ "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
+ ghost:
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
+ icon: "size-9",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+function Button({
+ className,
+ variant,
+ size,
+ asChild = false,
+ ...props
+}: React.ComponentProps<"button"> &
+ VariantProps & {
+ asChild?: boolean
+ }) {
+ const Comp = asChild ? Slot : "button"
+
+ return (
+
+ )
+}
+
+export { Button, buttonVariants }
diff --git a/packages/midnight-setup/ui/src/components/ui/card.tsx b/packages/midnight-setup/ui/src/components/ui/card.tsx
new file mode 100644
index 000000000..d05bbc6c7
--- /dev/null
+++ b/packages/midnight-setup/ui/src/components/ui/card.tsx
@@ -0,0 +1,92 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Card({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardAction({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardContent({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+export {
+ Card,
+ CardHeader,
+ CardFooter,
+ CardTitle,
+ CardAction,
+ CardDescription,
+ CardContent,
+}
diff --git a/packages/midnight-setup/ui/src/components/ui/dialog.tsx b/packages/midnight-setup/ui/src/components/ui/dialog.tsx
new file mode 100644
index 000000000..6cb123b38
--- /dev/null
+++ b/packages/midnight-setup/ui/src/components/ui/dialog.tsx
@@ -0,0 +1,141 @@
+import * as React from "react"
+import * as DialogPrimitive from "@radix-ui/react-dialog"
+import { XIcon } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+function Dialog({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogTrigger({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogPortal({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogClose({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogOverlay({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DialogContent({
+ className,
+ children,
+ showCloseButton = true,
+ ...props
+}: React.ComponentProps & {
+ showCloseButton?: boolean
+}) {
+ return (
+
+
+
+ {children}
+ {showCloseButton && (
+
+
+ Close
+
+ )}
+
+
+ )
+}
+
+function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function DialogTitle({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DialogDescription({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogOverlay,
+ DialogPortal,
+ DialogTitle,
+ DialogTrigger,
+}
diff --git a/packages/midnight-setup/ui/src/components/ui/input.tsx b/packages/midnight-setup/ui/src/components/ui/input.tsx
new file mode 100644
index 000000000..03295ca6a
--- /dev/null
+++ b/packages/midnight-setup/ui/src/components/ui/input.tsx
@@ -0,0 +1,21 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Input({ className, type, ...props }: React.ComponentProps<"input">) {
+ return (
+
+ )
+}
+
+export { Input }
diff --git a/packages/midnight-setup/ui/src/components/ui/label.tsx b/packages/midnight-setup/ui/src/components/ui/label.tsx
new file mode 100644
index 000000000..ef7133a75
--- /dev/null
+++ b/packages/midnight-setup/ui/src/components/ui/label.tsx
@@ -0,0 +1,22 @@
+import * as React from "react"
+import * as LabelPrimitive from "@radix-ui/react-label"
+
+import { cn } from "@/lib/utils"
+
+function Label({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export { Label }
diff --git a/packages/midnight-setup/ui/src/components/ui/progress.tsx b/packages/midnight-setup/ui/src/components/ui/progress.tsx
new file mode 100644
index 000000000..e7a416c37
--- /dev/null
+++ b/packages/midnight-setup/ui/src/components/ui/progress.tsx
@@ -0,0 +1,31 @@
+"use client"
+
+import * as React from "react"
+import * as ProgressPrimitive from "@radix-ui/react-progress"
+
+import { cn } from "@/lib/utils"
+
+function Progress({
+ className,
+ value,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+export { Progress }
diff --git a/packages/midnight-setup/ui/src/components/ui/textarea.tsx b/packages/midnight-setup/ui/src/components/ui/textarea.tsx
new file mode 100644
index 000000000..7f21b5e78
--- /dev/null
+++ b/packages/midnight-setup/ui/src/components/ui/textarea.tsx
@@ -0,0 +1,18 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
+ return (
+
+ )
+}
+
+export { Textarea }
diff --git a/packages/midnight-setup/ui/src/hookes/useMidnightWallet.tsx b/packages/midnight-setup/ui/src/hookes/useMidnightWallet.tsx
new file mode 100644
index 000000000..2ef1d3716
--- /dev/null
+++ b/packages/midnight-setup/ui/src/hookes/useMidnightWallet.tsx
@@ -0,0 +1,12 @@
+import { MidnightWalletContext } from '@/providers/MidnightWalletProvider'
+import { useContext } from 'react'
+
+export const useMidnightWallet = () => {
+ const context = useContext(MidnightWalletContext)
+ if(!context){
+ return;
+ }
+ return context;
+}
+
+export default useMidnightWallet
\ No newline at end of file
diff --git a/packages/midnight-setup/ui/src/index.css b/packages/midnight-setup/ui/src/index.css
new file mode 100644
index 000000000..5a7873abc
--- /dev/null
+++ b/packages/midnight-setup/ui/src/index.css
@@ -0,0 +1,2 @@
+@import "tailwindcss";
+@import "tw-animate-css";
diff --git a/packages/midnight-setup/ui/src/lib/actions.ts b/packages/midnight-setup/ui/src/lib/actions.ts
new file mode 100644
index 000000000..48e58deaa
--- /dev/null
+++ b/packages/midnight-setup/ui/src/lib/actions.ts
@@ -0,0 +1,226 @@
+import { type ContractAddress } from "@midnight-ntwrk/compact-runtime";
+import {
+ concatMap,
+ filter,
+ firstValueFrom,
+ interval,
+ map,
+ of,
+ take,
+ tap,
+ throwError,
+ timeout,
+ catchError,
+} from "rxjs";
+import { pipe as fnPipe } from "fp-ts/function";
+import {
+ type DAppConnectorAPI,
+ type DAppConnectorWalletAPI,
+ type ServiceUriConfig,
+} from "@midnight-ntwrk/dapp-connector-api";
+import { levelPrivateStateProvider } from "@midnight-ntwrk/midnight-js-level-private-state-provider";
+import { FetchZkConfigProvider } from "@midnight-ntwrk/midnight-js-fetch-zk-config-provider";
+import { httpClientProofProvider } from "@midnight-ntwrk/midnight-js-http-client-proof-provider";
+import { indexerPublicDataProvider } from "@midnight-ntwrk/midnight-js-indexer-public-data-provider";
+import {
+ type BalancedTransaction,
+ type UnbalancedTransaction,
+ createBalancedTx,
+} from "@midnight-ntwrk/midnight-js-types";
+import {
+ type CoinInfo,
+ Transaction,
+ type TransactionId,
+} from "@midnight-ntwrk/ledger";
+import { Transaction as ZswapTransaction } from "@midnight-ntwrk/zswap";
+import semver from "semver";
+import {
+ getLedgerNetworkId,
+ getZswapNetworkId,
+} from "@midnight-ntwrk/midnight-js-network-id";
+import {
+ MidnightSetupAPI,
+ type MidnightSetupContractProviders,
+ type DeployedMidnightSetupAPI,
+ type TokenCircuitKeys,
+} from "@meshsdk/midnight-setup";
+import type { WalletAndProvider } from "./common-types";
+import type { Logger } from "pino";
+
+const connectWallet = async (): Promise<{
+ wallet: DAppConnectorWalletAPI;
+ uris: ServiceUriConfig;
+}> => {
+ const COMPATIBLE_CONNECTOR_API_VERSION = "1.x";
+ return firstValueFrom(
+ fnPipe(
+ interval(100),
+ map(() => window.midnight?.mnLace),
+ tap((connectorAPI) => {
+ console.info(connectorAPI, "Check for wallet connector API");
+ }),
+ filter(
+ (connectorAPI): connectorAPI is DAppConnectorAPI => !!connectorAPI
+ ),
+ concatMap((connectorAPI) =>
+ semver.satisfies(
+ connectorAPI.apiVersion,
+ COMPATIBLE_CONNECTOR_API_VERSION
+ )
+ ? of(connectorAPI)
+ : throwError(() => {
+ console.error(
+ {
+ expected: COMPATIBLE_CONNECTOR_API_VERSION,
+ actual: connectorAPI.apiVersion,
+ },
+ "Incompatible version of wallet connector API"
+ );
+
+ return new Error(
+ `Incompatible version of Midnight Lace wallet found. Require '${COMPATIBLE_CONNECTOR_API_VERSION}', got '${connectorAPI.apiVersion}'.`
+ );
+ })
+ ),
+ tap((connectorAPI) => {
+ console.info(
+ connectorAPI,
+ "Compatible wallet connector API found. Connecting."
+ );
+ }),
+ take(1),
+ timeout({
+ first: 1_000,
+ with: () =>
+ throwError(() => {
+ console.error("Could not find wallet connector API");
+
+ return new Error(
+ "Could not find Midnight Lace wallet. Extension installed?"
+ );
+ }),
+ }),
+ concatMap(async (connectorAPI) => {
+ const isEnabled = await connectorAPI.isEnabled();
+
+ console.info(isEnabled, "Wallet connector API enabled status");
+
+ return connectorAPI;
+ }),
+ timeout({
+ first: 5_000,
+ with: () =>
+ throwError(() => {
+ console.error("Wallet connector API has failed to respond");
+
+ return new Error(
+ "Midnight Lace wallet has failed to respond. Extension enabled?"
+ );
+ }),
+ }),
+ concatMap(async (connectorAPI) => ({
+ walletConnectorAPI: await connectorAPI.enable(),
+ connectorAPI,
+ })),
+ catchError((error, apis) =>
+ error
+ ? throwError(() => {
+ console.error("Unable to enable connector API");
+ return new Error("Application is not authorized");
+ })
+ : apis
+ ),
+ concatMap(async ({ walletConnectorAPI, connectorAPI }) => {
+ const uris = await connectorAPI.serviceUriConfig();
+
+ console.info(
+ "Connected to wallet connector API and retrieved service configuration"
+ );
+
+ return { wallet: walletConnectorAPI, uris };
+ })
+ )
+ );
+};
+
+export const initialWalletAndProviders =
+ async (): Promise => {
+ const { wallet, uris } = await connectWallet();
+ const walletState = await wallet.state();
+
+ const providers = {
+ privateStateProvider: levelPrivateStateProvider({
+ privateStateStoreName: "midnight-setup-private-state",
+ }),
+ zkConfigProvider: new FetchZkConfigProvider(
+ window.location.origin,
+ fetch.bind(window)
+ ),
+ proofProvider: httpClientProofProvider(uris.proverServerUri),
+ publicDataProvider: indexerPublicDataProvider(
+ uris.indexerUri,
+ uris.indexerWsUri
+ ),
+ walletProvider: {
+ coinPublicKey: walletState.coinPublicKey,
+ encryptionPublicKey: walletState.encryptionPublicKey,
+ balanceTx(
+ tx: UnbalancedTransaction,
+ newCoins: CoinInfo[]
+ ): Promise {
+ return wallet
+ .balanceAndProveTransaction(
+ ZswapTransaction.deserialize(
+ tx.serialize(getLedgerNetworkId()),
+ getZswapNetworkId()
+ ),
+ newCoins
+ )
+ .then((zswapTx) =>
+ Transaction.deserialize(
+ zswapTx.serialize(getZswapNetworkId()),
+ getLedgerNetworkId()
+ )
+ )
+ .then(createBalancedTx)
+ .finally(() => {
+ console.log("balanceTxDone");
+ });
+ },
+ },
+ midnightProvider: {
+ submitTx(tx: BalancedTransaction): Promise {
+ return wallet.submitTransaction(tx);
+ },
+ },
+ };
+
+ return { wallet, uris, providers };
+ };
+
+export const resolve = async (
+ providers: MidnightSetupContractProviders,
+ logger: Logger,
+ contractAddress?: ContractAddress
+): Promise => {
+ let api;
+ if (contractAddress) {
+ api = await MidnightSetupAPI.joinMidnightSetupContract(
+ providers,
+ contractAddress
+ );
+ } else {
+ api = await MidnightSetupAPI.deployMidnightSetupContract(providers, logger);
+ }
+
+ return api;
+};
+
+export const calculateExpiryDate = (duration: number, creationDate: number) => {
+ const millisecondsPerHour = 1000 * 60 * 60 * 24;
+ const durationInMilliseconds = millisecondsPerHour * duration;
+ const expiryDate = creationDate + durationInMilliseconds;
+
+ const dateObject = new Date(expiryDate);
+ return dateObject.toLocaleDateString();
+};
diff --git a/packages/midnight-setup/ui/src/lib/common-types.ts b/packages/midnight-setup/ui/src/lib/common-types.ts
new file mode 100644
index 000000000..48f438c0a
--- /dev/null
+++ b/packages/midnight-setup/ui/src/lib/common-types.ts
@@ -0,0 +1,22 @@
+import type { MidnightSetupContractProviders, DeployedMidnightSetupAPI } from "@meshsdk/midnight-setup";
+import type { DAppConnectorWalletAPI, ServiceUriConfig } from "@midnight-ntwrk/dapp-connector-api";
+
+
+export interface WalletAndProvider{
+ readonly wallet: DAppConnectorWalletAPI,
+ readonly uris: ServiceUriConfig,
+ readonly providers: MidnightSetupContractProviders
+}
+
+export interface WalletAPI {
+ wallet: DAppConnectorWalletAPI;
+ coinPublicKey: string;
+ encryptionPublicKey: string;
+ uris: ServiceUriConfig;
+}
+
+
+export interface MidnightSetupDeployment{
+ status: "inprogress" | "deployed" | "failed",
+ api: DeployedMidnightSetupAPI;
+}
\ No newline at end of file
diff --git a/packages/midnight-setup/ui/src/lib/utils.ts b/packages/midnight-setup/ui/src/lib/utils.ts
new file mode 100644
index 000000000..bd0c391dd
--- /dev/null
+++ b/packages/midnight-setup/ui/src/lib/utils.ts
@@ -0,0 +1,6 @@
+import { clsx, type ClassValue } from "clsx"
+import { twMerge } from "tailwind-merge"
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs))
+}
diff --git a/packages/midnight-setup/ui/src/main.tsx b/packages/midnight-setup/ui/src/main.tsx
new file mode 100644
index 000000000..1ffd831da
--- /dev/null
+++ b/packages/midnight-setup/ui/src/main.tsx
@@ -0,0 +1,31 @@
+import { StrictMode } from "react";
+import './polyfills'
+import { createRoot } from "react-dom/client";
+import "./index.css";
+import App from "./App.tsx";
+import MidnightWalletProvider from "./providers/MidnightWalletProvider.tsx";
+import DeployedContractProvider from "./providers/DeployedContractProvider.tsx";
+import pino from "pino";
+import { setNetworkId, type NetworkId } from "@midnight-ntwrk/midnight-js-network-id";
+
+const networkId = import.meta.env.VITE_NETWORK_ID as NetworkId;
+// Ensure that the network IDs are set within the Midnight libraries.
+setNetworkId(networkId);
+
+// Create a default `pino` logger and configure it with the configured logging level.
+export const logger = pino({
+ level: import.meta.env.VITE_LOGGING_LEVEL as string,
+});
+
+logger.trace('networkId = ', networkId);
+
+createRoot(document.getElementById("root")!).render(
+
+
+
+
+
+
+
+);
+
diff --git a/packages/midnight-setup/ui/src/polyfills.ts b/packages/midnight-setup/ui/src/polyfills.ts
new file mode 100644
index 000000000..ad66ba461
--- /dev/null
+++ b/packages/midnight-setup/ui/src/polyfills.ts
@@ -0,0 +1,10 @@
+// src/polyfills.ts - Create this file
+import { Buffer } from 'buffer'
+
+// Make Buffer available globally
+window.Buffer = Buffer
+window.global = window.global || window
+window.process = window.process || { env: {} }
+
+// Export for direct imports
+export { Buffer }
\ No newline at end of file
diff --git a/packages/midnight-setup/ui/src/providers/DeployedContractProvider.tsx b/packages/midnight-setup/ui/src/providers/DeployedContractProvider.tsx
new file mode 100644
index 000000000..35c736961
--- /dev/null
+++ b/packages/midnight-setup/ui/src/providers/DeployedContractProvider.tsx
@@ -0,0 +1,160 @@
+import useMidnightWallet from "@/hookes/useMidnightWallet";
+import { MidnightSetupAPI, type DeployedMidnightSetupAPI } from "@meshsdk/midnight-setup";
+import type { Logger } from "pino";
+import {
+ createContext,
+ useCallback,
+ useContext,
+ useState,
+ type PropsWithChildren,
+} from "react";
+
+export interface DeploymentProvider {
+ readonly isJoining: boolean;
+ readonly isDeploying: boolean;
+ readonly error: string | null;
+ readonly hasJoined: boolean;
+ readonly hasDeployed: boolean;
+ readonly midnightSetupApi: DeployedMidnightSetupAPI | undefined;
+ readonly deployedContractAddress: string | undefined;
+ onJoinContract: (address: string) => Promise;
+ onDeployContract: () => Promise;
+ clearError: () => void;
+}
+
+export const DeployedContractContext = createContext(null);
+
+interface DeployedContractProviderProps extends PropsWithChildren {
+ logger?: Logger;
+}
+
+const DeployedContractProvider = ({
+ children,
+ logger
+}: DeployedContractProviderProps) => {
+
+ const [midnightSetupApi, setMidnightSetupApi] = useState(undefined);
+ const [isJoining, setIsJoining] = useState(false);
+ const [isDeploying, setIsDeploying] = useState(false);
+ const [error, setError] = useState(null);
+ const [hasJoined, setHasJoined] = useState(false);
+ const [hasDeployed, setHasDeployed] = useState(false);
+ const [deployedContractAddress, setDeployedContractAddress] = useState(undefined);
+
+ // Use the custom hook instead of useContext directly
+ const walletContext = useMidnightWallet();
+
+ const onJoinContract = useCallback(async (address: string) => {
+ // Prevent multiple simultaneous joins
+ if (isJoining || hasJoined || isDeploying || hasDeployed) return;
+
+ // Validate requirements
+ if (!walletContext?.walletState.hasConnected || !walletContext?.walletState.providers) {
+ setError("Wallet must be connected before joining contract");
+ return;
+ }
+
+ if (!address) {
+ setError("Contract address is required");
+ return;
+ }
+
+ setIsJoining(true);
+ setError(null);
+
+ try {
+ const deployedAPI = await MidnightSetupAPI.joinMidnightSetupContract(
+ walletContext.walletState.providers,
+ address,
+ logger
+ );
+
+ setMidnightSetupApi(deployedAPI);
+ setHasJoined(true);
+ setDeployedContractAddress(deployedAPI.deployedContractAddress);
+ logger?.info("Successfully joined contract", { contractAddress: address });
+
+ } catch (error) {
+ const errMsg = error instanceof Error
+ ? error.message
+ : `Failed to join contract at ${address}`;
+ setError(errMsg);
+ logger?.error("Failed to join contract", { error: errMsg, contractAddress: address });
+ } finally {
+ setIsJoining(false);
+ }
+ }, [isJoining, hasJoined, isDeploying, hasDeployed, walletContext?.walletState.hasConnected, walletContext?.walletState.providers, logger]);
+
+ const onDeployContract = useCallback(async () => {
+ // Prevent multiple simultaneous operations
+ if (isDeploying || hasDeployed || isJoining || hasJoined) return;
+
+ // Validate requirements
+ if (!walletContext?.walletState.hasConnected || !walletContext?.walletState.providers) {
+ setError("Wallet must be connected before deploying contract");
+ return;
+ }
+
+ setIsDeploying(true);
+ setError(null);
+
+ try {
+ const deployedAPI = await MidnightSetupAPI.deployMidnightSetupContract(
+ walletContext.walletState.providers,
+ logger
+ );
+
+ setMidnightSetupApi(deployedAPI);
+ setHasDeployed(true);
+ setDeployedContractAddress(deployedAPI.deployedContractAddress);
+ logger?.info("Successfully deployed new contract", {
+ contractAddress: deployedAPI.deployedContractAddress
+ });
+
+ } catch (error) {
+ const errMsg = error instanceof Error
+ ? error.message
+ : "Failed to deploy new contract";
+ setError(errMsg);
+ logger?.error("Failed to deploy contract", { error: errMsg });
+ } finally {
+ setIsDeploying(false);
+ }
+ }, [isDeploying, hasDeployed, isJoining, hasJoined, walletContext?.walletState.hasConnected, walletContext?.walletState.providers, logger]);
+
+ const clearError = useCallback(() => {
+ setError(null);
+ }, []);
+
+ const contextValue: DeploymentProvider = {
+ isJoining,
+ isDeploying,
+ hasJoined,
+ hasDeployed,
+ error,
+ midnightSetupApi,
+ deployedContractAddress,
+ onJoinContract,
+ onDeployContract,
+ clearError,
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+// Custom hook for consuming the context
+export const useDeployedContract = (): DeploymentProvider => {
+ const context = useContext(DeployedContractContext);
+
+ if (!context) {
+ throw new Error("useDeployedContract must be used within a DeployedContractProvider");
+ }
+
+ return context;
+};
+
+export default DeployedContractProvider;
\ No newline at end of file
diff --git a/packages/midnight-setup/ui/src/providers/MidnightWalletProvider.tsx b/packages/midnight-setup/ui/src/providers/MidnightWalletProvider.tsx
new file mode 100644
index 000000000..e90d9a73c
--- /dev/null
+++ b/packages/midnight-setup/ui/src/providers/MidnightWalletProvider.tsx
@@ -0,0 +1,173 @@
+import { initialWalletAndProviders } from "@/lib/actions";
+import type { WalletAPI } from "@/lib/common-types";
+import type { MidnightSetupContractProviders } from "@meshsdk/midnight-setup";
+import type { Logger } from "pino";
+import {
+ createContext,
+ useReducer,
+ useCallback,
+ type PropsWithChildren,
+} from "react";
+
+export interface MidnightWalletState {
+ readonly address: string | undefined;
+ readonly isConnecting: boolean;
+ readonly coinPublicKey: string | undefined;
+ readonly providers: MidnightSetupContractProviders | undefined;
+ readonly walletAPI: WalletAPI | undefined;
+ readonly hasConnected: boolean;
+ readonly error: string | null;
+}
+
+export interface MidnightWalletContextType {
+ walletState: MidnightWalletState;
+ connectToWalletAndInitializeProviders: () => Promise;
+ disconnect: () => void;
+ clearError: () => void;
+}
+
+// Initial state
+const initialState: MidnightWalletState = {
+ address: undefined,
+ isConnecting: false,
+ coinPublicKey: undefined,
+ providers: undefined,
+ walletAPI: undefined,
+ hasConnected: false,
+ error: null,
+};
+
+// Action types
+type WalletAction =
+ | { type: "CONNECT_START" }
+ | {
+ type: "CONNECT_SUCCESS";
+ payload: Omit<
+ MidnightWalletState,
+ "isConnecting" | "hasConnected" | "error"
+ >;
+ }
+ | { type: "CONNECT_ERROR"; payload: string }
+ | { type: "DISCONNECT" }
+ | { type: "CLEAR_ERROR" };
+
+// Reducer
+function walletReducer(
+ state: MidnightWalletState,
+ action: WalletAction
+): MidnightWalletState {
+ switch (action.type) {
+ case "CONNECT_START":
+ return {
+ ...state,
+ isConnecting: true,
+ error: null,
+ };
+ case "CONNECT_SUCCESS":
+ return {
+ ...state,
+ ...action.payload,
+ isConnecting: false,
+ hasConnected: true,
+ error: null,
+ };
+ case "CONNECT_ERROR":
+ return {
+ ...state,
+ isConnecting: false,
+ error: action.payload,
+ };
+ case "DISCONNECT":
+ return {
+ ...initialState,
+ hasConnected: false,
+ };
+ case "CLEAR_ERROR":
+ return {
+ ...state,
+ error: null,
+ };
+ default:
+ return state;
+ }
+}
+
+// Context
+export const MidnightWalletContext =
+ createContext(null);
+
+// Provider Props
+interface MidnightWalletProviderProps extends PropsWithChildren {
+ logger?: Logger;
+}
+
+const MidnightWalletProvider = ({
+ children,
+ logger,
+}: MidnightWalletProviderProps) => {
+ const [walletState, dispatch] = useReducer(walletReducer, initialState);
+
+ const connectToWalletAndInitializeProviders = useCallback(async () => {
+ if (walletState.isConnecting) return; // Prevent multiple simultaneous connections
+
+ dispatch({ type: "CONNECT_START" });
+
+ try {
+ const { wallet, uris, providers } = await initialWalletAndProviders();
+
+ if (!wallet) {
+ throw new Error("Failed to initialize wallet");
+ }
+
+ const walletStateData = await wallet.state();
+
+ dispatch({
+ type: "CONNECT_SUCCESS",
+ payload: {
+ address: walletStateData.address,
+ coinPublicKey: walletStateData.coinPublicKey,
+ providers,
+ walletAPI: {
+ wallet,
+ uris,
+ coinPublicKey: walletStateData.coinPublicKey,
+ encryptionPublicKey: walletStateData.encryptionPublicKey,
+ },
+ },
+ });
+
+ logger?.info("Wallet connected successfully", {
+ address: walletStateData.address,
+ });
+ } catch (error) {
+ const errorMessage =
+ error instanceof Error ? error.message : "Failed to initialize wallet";
+ dispatch({ type: "CONNECT_ERROR", payload: errorMessage });
+ logger?.error("Wallet connection failed", { error: errorMessage });
+ }
+ }, [walletState.isConnecting, logger]);
+
+ const disconnect = useCallback(() => {
+ dispatch({ type: "DISCONNECT" });
+ logger?.info("Wallet disconnected");
+ }, [logger]);
+
+ const clearError = useCallback(() => {
+ dispatch({ type: "CLEAR_ERROR" });
+ }, []);
+
+ const contextValue: MidnightWalletContextType = {
+ walletState,
+ connectToWalletAndInitializeProviders,
+ disconnect,
+ clearError,
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export default MidnightWalletProvider;
diff --git a/packages/midnight-setup/ui/src/vite-env.d.ts b/packages/midnight-setup/ui/src/vite-env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/packages/midnight-setup/ui/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/packages/midnight-setup/ui/tailwind.config.js b/packages/midnight-setup/ui/tailwind.config.js
new file mode 100644
index 000000000..89a305e02
--- /dev/null
+++ b/packages/midnight-setup/ui/tailwind.config.js
@@ -0,0 +1,11 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+ content: [
+ "./index.html",
+ "./src/**/*.{js,ts,jsx,tsx}",
+ ],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+}
\ No newline at end of file
diff --git a/packages/midnight-setup/ui/tsconfig.app.json b/packages/midnight-setup/ui/tsconfig.app.json
new file mode 100644
index 000000000..f39faca89
--- /dev/null
+++ b/packages/midnight-setup/ui/tsconfig.app.json
@@ -0,0 +1,31 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ },
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["src"]
+}
diff --git a/packages/midnight-setup/ui/tsconfig.json b/packages/midnight-setup/ui/tsconfig.json
new file mode 100644
index 000000000..fec8c8e5c
--- /dev/null
+++ b/packages/midnight-setup/ui/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "files": [],
+ "references": [
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.node.json" }
+ ],
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/packages/midnight-setup/ui/tsconfig.node.json b/packages/midnight-setup/ui/tsconfig.node.json
new file mode 100644
index 000000000..f85a39906
--- /dev/null
+++ b/packages/midnight-setup/ui/tsconfig.node.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ "target": "ES2023",
+ "lib": ["ES2023"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/packages/midnight-setup/ui/vite.config.ts b/packages/midnight-setup/ui/vite.config.ts
new file mode 100644
index 000000000..17ee72c60
--- /dev/null
+++ b/packages/midnight-setup/ui/vite.config.ts
@@ -0,0 +1,44 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+import tailwindcss from "@tailwindcss/vite";
+import path from "path";
+import { viteCommonjs } from "@originjs/vite-plugin-commonjs";
+import wasm from "vite-plugin-wasm";
+import topLevelAwait from "vite-plugin-top-level-await";
+
+// https://vite.dev/config/
+export default defineConfig({
+ cacheDir: "./.vite",
+ build: {
+ target: "esnext",
+ minify: false,
+ },
+ plugins: [react(), tailwindcss(), wasm(), topLevelAwait(), viteCommonjs()],
+ resolve: {
+ alias: {
+ "@": path.resolve(__dirname, "./src"),
+ buffer: 'buffer',
+ process: 'process/browser',
+ util: 'util',
+ crypto: 'crypto-browserify',
+ stream: 'stream-browserify',
+ assert: 'assert',
+ http: 'stream-http',
+ https: 'https-browserify',
+ os: 'os-browserify',
+ url: 'url',
+ fs: 'browserify-fs',
+ },
+
+ },
+ optimizeDeps: {
+ esbuildOptions: {
+ target: "esnext",
+ },
+ include: [
+ 'buffer',
+ 'process',
+ ],
+ },
+ define: {},
+});