diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..024eaf49e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,42 @@ +# Build stage +FROM node:22-slim AS builder + +# Install build dependencies for native modules +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 \ + make \ + g++ \ + libcairo2-dev \ + libpango1.0-dev \ + libpng-dev \ + libjpeg-dev \ + libgif-dev \ + librsvg2-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +# Copy package files AND patches directory (needed for postinstall) +COPY package*.json ./ +COPY patches/ ./patches/ + +# Install dependencies +# Canvas may fail to build from source but it's optional, npm will continue +RUN npm ci + +# Copy source code +COPY . . + +# Build the application +RUN npm run build + +# Production stage with Caddy +FROM caddy:2-alpine + +# Copy built files from builder +COPY --from=builder /app/dist /usr/share/caddy + +EXPOSE 80 +EXPOSE 443 + +CMD ["caddy", "file-server", "--root", "/usr/share/caddy", "--listen", ":80"] diff --git a/package-lock.json b/package-lock.json index 55682155b..2f4624bd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,9 @@ "version": "2.3.3", "hasInstallScript": true, "dependencies": { + "@algorandecosystem/liquid-auth-use-wallet-client": "1.5.1", + "@algorandecosystem/use-wallet": "4.7.0-beta.1", + "@algorandecosystem/use-wallet-react": "4.7.0-beta.1", "@algorandfoundation/algokit-subscriber": "^4.0.0-alpha.6", "@algorandfoundation/algokit-utils": "^10.0.0-alpha.32", "@auth0/auth0-react": "^2.2.4", @@ -34,9 +37,8 @@ "@radix-ui/react-switch": "^1.2.5", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-store": "0.8.0", "@tanstack/react-table": "^8.16.0", - "@txnlab/use-wallet": "^4.0.0", - "@txnlab/use-wallet-react": "^4.0.0", "@xstate/react": "^5.0.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", @@ -119,6 +121,142 @@ "vitest": "^3.2.4" } }, + "../algorand-devrel-use-wallet/packages/use-wallet": { + "name": "@txnlab/use-wallet", + "version": "4.5.0", + "extraneous": true, + "license": "MIT", + "dependencies": { + "@tanstack/store": "0.8.0" + }, + "devDependencies": { + "@agoralabs-sh/avm-web-provider": "1.7.0", + "@algorandecosystem/liquid-auth-use-wallet-client": "github:algorandecosystem/liquid-auth-use-wallet-client#falcon24-support", + "@blockshake/defly-connect": "1.2.1", + "@magic-ext/algorand": "24.4.2", + "@magic-sdk/provider": "29.5.0", + "@perawallet/connect": "1.4.1", + "@types/node": "20.11.30", + "@walletconnect/modal": "2.7.0", + "@walletconnect/modal-core": "2.7.0", + "@walletconnect/sign-client": "2.23.4", + "@walletconnect/types": "2.23.4", + "@web3auth/base": "9.7.0", + "@web3auth/base-provider": "9.7.0", + "@web3auth/modal": "9.7.0", + "@web3auth/single-factor-auth": "9.5.0", + "algosdk": "3.5.2", + "canonify": "2.1.1", + "lute-connect": "1.6.3", + "magic-sdk": "29.4.2", + "tsup": "8.5.1", + "tweetnacl": "1.0.3", + "typescript": "5.9.3" + }, + "peerDependencies": { + "@agoralabs-sh/avm-web-provider": "^1.7.0", + "@algorandecosystem/liquid-auth-use-wallet-client": "*", + "@blockshake/defly-connect": "^1.2.1", + "@perawallet/connect": "^1.4.1", + "@walletconnect/modal": "^2.7.0", + "@walletconnect/sign-client": "^2.23.4", + "@web3auth/base": "^9.0.0", + "@web3auth/base-provider": "^9.0.0", + "@web3auth/modal": "^9.0.0", + "@web3auth/single-factor-auth": "^9.0.0", + "algosdk": "^3.0.0", + "lute-connect": "^1.6.3" + }, + "peerDependenciesMeta": { + "@agoralabs-sh/avm-web-provider": { + "optional": true + }, + "@algorandecosystem/liquid-auth-use-wallet-client": { + "optional": true + }, + "@blockshake/defly-connect": { + "optional": true + }, + "@perawallet/connect": { + "optional": true + }, + "@walletconnect/modal": { + "optional": true + }, + "@walletconnect/sign-client": { + "optional": true + }, + "@web3auth/base": { + "optional": true + }, + "@web3auth/base-provider": { + "optional": true + }, + "@web3auth/modal": { + "optional": true + }, + "@web3auth/single-factor-auth": { + "optional": true + }, + "lute-connect": { + "optional": true + } + } + }, + "../algorand-devrel-use-wallet/packages/use-wallet-react": { + "name": "@txnlab/use-wallet-react", + "version": "4.5.0", + "extraneous": true, + "license": "MIT", + "dependencies": { + "@tanstack/react-store": "0.8.0", + "@txnlab/use-wallet": "workspace:*" + }, + "devDependencies": { + "@types/react": "18.3.27", + "algosdk": "3.5.2", + "jsdom": "26.1.0", + "react": "18.3.1", + "react-dom": "18.3.1", + "tsup": "8.5.1", + "typescript": "5.9.3" + }, + "peerDependencies": { + "@blockshake/defly-connect": "^1.2.1", + "@magic-ext/algorand": "^24.4.2", + "@perawallet/connect": "^1.4.1", + "@walletconnect/modal": "^2.7.0", + "@walletconnect/sign-client": "^2.23.4", + "algosdk": "^3.0.0", + "lute-connect": "^1.6.3", + "magic-sdk": "^29.4.2", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@blockshake/defly-connect": { + "optional": true + }, + "@magic-ext/algorand": { + "optional": true + }, + "@perawallet/connect": { + "optional": true + }, + "@walletconnect/modal": { + "optional": true + }, + "@walletconnect/sign-client": { + "optional": true + }, + "lute-connect": { + "optional": true + }, + "magic-sdk": { + "optional": true + } + } + }, "node_modules/@actions/core": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz", @@ -189,6 +327,133 @@ "dev": true, "license": "MIT" }, + "node_modules/@algorandecosystem/liquid-auth-use-wallet-client": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@algorandecosystem/liquid-auth-use-wallet-client/-/liquid-auth-use-wallet-client-1.5.1.tgz", + "integrity": "sha512-n4KTvZBE/rWszBod+LmNgWIMhI9EqMtBWudaQiHOY7FPIUTmXcP66JUiCZa569xNyw7BH2bg61UEk++FIojz+g==", + "license": "AGPL-3.0", + "dependencies": { + "@algorandecosystem/liquid-client": "^1.0.0", + "@algorandfoundation/provider": "github:algorandfoundation/wallet-provider-ts", + "cbor": "^10.0.11" + } + }, + "node_modules/@algorandecosystem/liquid-client": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@algorandecosystem/liquid-client/-/liquid-client-1.0.0.tgz", + "integrity": "sha512-T3MUF0mwT6Xiq53skYcam0sud0OkDZ3cbRGtiUIWqmO2oUFOlI5coIdtSyMQvCjc2DKlX22yx5HLjBLqsxFvHA==", + "license": "Apache-2.0", + "dependencies": { + "eventemitter3": "^5.0.1", + "qrcode": "^1.5.4", + "socket.io-client": "^4.7.5", + "tweetnacl": "^1.0.3", + "uuid": "^10.0.0" + } + }, + "node_modules/@algorandecosystem/use-wallet": { + "version": "4.7.0-beta.1", + "resolved": "https://registry.npmjs.org/@algorandecosystem/use-wallet/-/use-wallet-4.7.0-beta.1.tgz", + "integrity": "sha512-tb938dWPTTsNbIp/qzDCcIC0F7+Mx6w49bx8DCXG/3HbjDoZQwHVROLeT+gvrBb45v+7XelHn9to2ZDkRnlaKg==", + "license": "MIT", + "dependencies": { + "@tanstack/store": "0.8.0" + }, + "peerDependencies": { + "@agoralabs-sh/avm-web-provider": "^1.7.0", + "@algorandecosystem/liquid-auth-use-wallet-client": "*", + "@blockshake/defly-connect": "^1.2.1", + "@perawallet/connect": "^1.4.1", + "@walletconnect/modal": "^2.7.0", + "@walletconnect/sign-client": "^2.23.4", + "@web3auth/base": "^9.0.0", + "@web3auth/base-provider": "^9.0.0", + "@web3auth/modal": "^9.0.0", + "@web3auth/single-factor-auth": "^9.0.0", + "algosdk": "^3.0.0", + "lute-connect": "^1.6.3" + }, + "peerDependenciesMeta": { + "@agoralabs-sh/avm-web-provider": { + "optional": true + }, + "@algorandecosystem/liquid-auth-use-wallet-client": { + "optional": true + }, + "@blockshake/defly-connect": { + "optional": true + }, + "@perawallet/connect": { + "optional": true + }, + "@walletconnect/modal": { + "optional": true + }, + "@walletconnect/sign-client": { + "optional": true + }, + "@web3auth/base": { + "optional": true + }, + "@web3auth/base-provider": { + "optional": true + }, + "@web3auth/modal": { + "optional": true + }, + "@web3auth/single-factor-auth": { + "optional": true + }, + "lute-connect": { + "optional": true + } + } + }, + "node_modules/@algorandecosystem/use-wallet-react": { + "version": "4.7.0-beta.1", + "resolved": "https://registry.npmjs.org/@algorandecosystem/use-wallet-react/-/use-wallet-react-4.7.0-beta.1.tgz", + "integrity": "sha512-xKizlTvTn3IxbrVisy19FN3Cvh45yTt1wF3GcKj9SVnbRWFih6ir9GutYxr7kOymgZau5P5XsSe7t+HtStjjwg==", + "license": "MIT", + "dependencies": { + "@algorandecosystem/use-wallet": "4.7.0-beta.1", + "@tanstack/react-store": "0.8.0" + }, + "peerDependencies": { + "@blockshake/defly-connect": "^1.2.1", + "@magic-ext/algorand": "^24.4.2", + "@perawallet/connect": "^1.4.1", + "@walletconnect/modal": "^2.7.0", + "@walletconnect/sign-client": "^2.23.4", + "algosdk": "^3.0.0", + "lute-connect": "^1.6.3", + "magic-sdk": "^29.4.2", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@blockshake/defly-connect": { + "optional": true + }, + "@magic-ext/algorand": { + "optional": true + }, + "@perawallet/connect": { + "optional": true + }, + "@walletconnect/modal": { + "optional": true + }, + "@walletconnect/sign-client": { + "optional": true + }, + "lute-connect": { + "optional": true + }, + "magic-sdk": { + "optional": true + } + } + }, "node_modules/@algorandfoundation/algokit-subscriber": { "version": "4.0.0-alpha.6", "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-subscriber/-/algokit-subscriber-4.0.0-alpha.6.tgz", @@ -228,6 +493,14 @@ "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==", "license": "MIT" }, + "node_modules/@algorandfoundation/provider": { + "version": "0.0.1", + "resolved": "git+ssh://git@github.com/algorandfoundation/wallet-provider-ts.git#28c80f5b9e0259b8e83e65c65d802d8123de9046", + "license": "AGPL-3.0-or-later", + "dependencies": { + "cbor-x": "^1.6.0" + } + }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -317,6 +590,84 @@ "algosdk": "^3.0.0" } }, + "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", + "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@cbor-extract/cbor-extract-darwin-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", + "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-arm": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", + "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", + "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", + "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-win32-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", + "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -4193,6 +4544,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, "node_modules/@swc/core": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.0.tgz", @@ -4706,13 +5063,13 @@ } }, "node_modules/@tanstack/react-store": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.7.3.tgz", - "integrity": "sha512-3Dnqtbw9P2P0gw8uUM8WP2fFfg8XMDSZCTsywRPZe/XqqYW8PGkXKZTvP0AHkE4mpqP9Y43GpOg9vwO44azu6Q==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.8.0.tgz", + "integrity": "sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow==", "license": "MIT", "dependencies": { - "@tanstack/store": "0.7.2", - "use-sync-external-store": "^1.5.0" + "@tanstack/store": "0.8.0", + "use-sync-external-store": "^1.6.0" }, "funding": { "type": "github", @@ -4744,9 +5101,9 @@ } }, "node_modules/@tanstack/store": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.7.2.tgz", - "integrity": "sha512-RP80Z30BYiPX2Pyo0Nyw4s1SJFH2jyM6f9i3HfX4pA+gm5jsnYryscdq2aIQLnL4TaGuQMO+zXmN9nh1Qck+Pg==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.8.0.tgz", + "integrity": "sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ==", "license": "MIT", "funding": { "type": "github", @@ -4850,114 +5207,31 @@ "pretty-format": "^27.0.2" }, "engines": { - "node": ">=14" - } - }, - "node_modules/@testing-library/react/node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/@testing-library/user-event": { - "version": "14.6.1", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", - "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12", - "npm": ">=6" - }, - "peerDependencies": { - "@testing-library/dom": ">=7.21.4" - } - }, - "node_modules/@txnlab/use-wallet": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@txnlab/use-wallet/-/use-wallet-4.3.1.tgz", - "integrity": "sha512-kWDOauxROjwmnOmivp5iBAXqdksYHDXaP7P/AbX/uawnv+H+WQiP0dBUKnVLb//eOUbhq7QT33yUGGXC6QATgQ==", - "license": "MIT", - "dependencies": { - "@tanstack/store": "0.7.2" - }, - "peerDependencies": { - "@agoralabs-sh/avm-web-provider": "^1.7.0", - "@blockshake/defly-connect": "^1.2.1", - "@perawallet/connect": "^1.4.1", - "@walletconnect/modal": "^2.7.0", - "@walletconnect/sign-client": "^2.21.8", - "algosdk": "^3.0.0", - "lute-connect": "^1.6.2" - }, - "peerDependenciesMeta": { - "@agoralabs-sh/avm-web-provider": { - "optional": true - }, - "@blockshake/defly-connect": { - "optional": true - }, - "@perawallet/connect": { - "optional": true - }, - "@walletconnect/modal": { - "optional": true - }, - "@walletconnect/sign-client": { - "optional": true - }, - "lute-connect": { - "optional": true - } + "node": ">=14" } }, - "node_modules/@txnlab/use-wallet-react": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@txnlab/use-wallet-react/-/use-wallet-react-4.3.1.tgz", - "integrity": "sha512-Gmj1qBNykx2HbFS4FzzqCa8uWI4UkdYw2mk6a+62AVoKU2/hvPe9K6DvdDrc883dJoRSK0xPtSGjJ6lKxT1bCQ==", - "license": "MIT", + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@tanstack/react-store": "0.7.3", - "@txnlab/use-wallet": "4.3.1" + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" }, "peerDependencies": { - "@blockshake/defly-connect": "^1.2.1", - "@magic-ext/algorand": "^24.4.2", - "@perawallet/connect": "^1.4.1", - "@walletconnect/modal": "^2.7.0", - "@walletconnect/sign-client": "^2.21.8", - "algosdk": "^3.0.0", - "lute-connect": "^1.6.2", - "magic-sdk": "^29.4.2", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@blockshake/defly-connect": { - "optional": true - }, - "@magic-ext/algorand": { - "optional": true - }, - "@perawallet/connect": { - "optional": true - }, - "@walletconnect/modal": { - "optional": true - }, - "@walletconnect/sign-client": { - "optional": true - }, - "lute-connect": { - "optional": true - }, - "magic-sdk": { - "optional": true - } + "@testing-library/dom": ">=7.21.4" } }, "node_modules/@types/aria-query": { @@ -6536,7 +6810,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -6560,6 +6833,49 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cbor": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-10.0.11.tgz", + "integrity": "sha512-vIwORDd/WyB8Nc23o2zNN5RrtFGlR6Fca61TtjkUXueI3Jf2DOZDl1zsshvBntZ3wZHBM9ztjnkXSmzQDaq3WA==", + "license": "MIT", + "dependencies": { + "nofilter": "^3.0.2" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cbor-extract": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", + "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.1.1" + }, + "bin": { + "download-cbor-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", + "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", + "@cbor-extract/cbor-extract-linux-x64": "2.2.0", + "@cbor-extract/cbor-extract-win32-x64": "2.2.0" + } + }, + "node_modules/cbor-x": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.6.0.tgz", + "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==", + "license": "MIT", + "optionalDependencies": { + "cbor-extract": "^2.2.0" + } + }, "node_modules/chai": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", @@ -7385,7 +7701,6 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -7403,7 +7718,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7578,7 +7892,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -7602,6 +7916,12 @@ "randombytes": "^2.0.0" } }, + "node_modules/dijkstrajs": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", + "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==", + "license": "MIT" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -7731,6 +8051,49 @@ "dev": true, "license": "MIT" }, + "node_modules/engine.io-client": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.4.tgz", + "integrity": "sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.18.3", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.18.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", @@ -8493,6 +8856,12 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -11549,7 +11918,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/msw": { @@ -11686,6 +12054,21 @@ "node": ">=18" } }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, "node_modules/node-stdlib-browser": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-stdlib-browser/-/node-stdlib-browser-1.3.1.tgz", @@ -11765,6 +12148,15 @@ "node": ">= 6" } }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "license": "MIT", + "engines": { + "node": ">=12.19" + } + }, "node_modules/normalize-package-data": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", @@ -14591,7 +14983,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14830,6 +15221,15 @@ "pathe": "^2.0.3" } }, + "node_modules/pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -15096,12 +15496,142 @@ "integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==", "license": "MIT" }, + "node_modules/qrcode": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", + "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", + "license": "MIT", + "dependencies": { + "dijkstrajs": "^1.0.1", + "pngjs": "^5.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "qrcode": "bin/qrcode" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/qrcode-generator": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.5.2.tgz", "integrity": "sha512-pItrW0Z9HnDBnFmgiNrY1uxRdri32Uh9EjNYLPVC2zZ3ZRIIEqBoDgm4DkvDwNNDHTK7FNkmr8zAa77BYc9xNw==", "license": "MIT" }, + "node_modules/qrcode/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/qrcode/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/qrcode/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qrcode/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "license": "ISC" + }, + "node_modules/qrcode/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.14.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", @@ -15810,6 +16340,12 @@ "node": ">=0.10.0" } }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "license": "ISC" + }, "node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -16668,6 +17204,12 @@ "node": ">=10" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -17042,6 +17584,34 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/socket.io-client": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.3.tgz", + "integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.5.tgz", + "integrity": "sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -18820,6 +19390,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "license": "ISC" + }, "node_modules/which-typed-array": { "version": "1.1.19", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", @@ -18911,6 +19487,14 @@ } } }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/xstate": { "version": "5.24.0", "resolved": "https://registry.npmjs.org/xstate/-/xstate-5.24.0.tgz", diff --git a/package.json b/package.json index d87583b99..604bb27c2 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,9 @@ "postinstall": "patch-package" }, "dependencies": { + "@algorandecosystem/liquid-auth-use-wallet-client": "1.5.1", + "@algorandecosystem/use-wallet": "4.7.0-beta.1", + "@algorandecosystem/use-wallet-react": "4.7.0-beta.1", "@algorandfoundation/algokit-subscriber": "^4.0.0-alpha.6", "@algorandfoundation/algokit-utils": "^10.0.0-alpha.32", "@auth0/auth0-react": "^2.2.4", @@ -50,9 +53,8 @@ "@radix-ui/react-switch": "^1.2.5", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-store": "0.8.0", "@tanstack/react-table": "^8.16.0", - "@txnlab/use-wallet": "^4.0.0", - "@txnlab/use-wallet-react": "^4.0.0", "@xstate/react": "^5.0.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", diff --git a/src/features/app-interfaces/components/create/deploy-app.tsx b/src/features/app-interfaces/components/create/deploy-app.tsx index 7fc2529c6..b2a8cd6cc 100644 --- a/src/features/app-interfaces/components/create/deploy-app.tsx +++ b/src/features/app-interfaces/components/create/deploy-app.tsx @@ -7,7 +7,7 @@ import { BuildMethodCallTransactionResult, BuildTransactionResult, } from '@/features/transaction-wizard/models' -import { useWallet } from '@txnlab/use-wallet-react' +import { useWallet } from '@algorandecosystem/use-wallet-react' import { DialogBodyProps, useDialogForm } from '@/features/common/hooks/use-dialog-form' import { TransactionType } from '@algorandfoundation/algokit-utils/transact' import { OnApplicationComplete } from '@algorandfoundation/algokit-utils/transact' diff --git a/src/features/app-interfaces/components/create/from-deployment-card.tsx b/src/features/app-interfaces/components/create/from-deployment-card.tsx index c9278b483..4f1ada91d 100644 --- a/src/features/app-interfaces/components/create/from-deployment-card.tsx +++ b/src/features/app-interfaces/components/create/from-deployment-card.tsx @@ -2,7 +2,7 @@ import { useCallback, useMemo } from 'react' import { useCreateAppInterfaceStateMachine } from '../../data' import { Card, CardContent } from '@/features/common/components/card' import { Button } from '@/features/common/components/button' -import { useWallet } from '@txnlab/use-wallet-react' +import { useWallet } from '@algorandecosystem/use-wallet-react' import { deployAppLabel } from '../labels' type Props = { diff --git a/src/features/app-interfaces/pages/create-app-interface-page.test.tsx b/src/features/app-interfaces/pages/create-app-interface-page.test.tsx index 9d59be1a6..aa290c6f9 100644 --- a/src/features/app-interfaces/pages/create-app-interface-page.test.tsx +++ b/src/features/app-interfaces/pages/create-app-interface-page.test.tsx @@ -5,7 +5,7 @@ import { algorandFixture } from '@algorandfoundation/algokit-utils/testing' import { afterEach, beforeEach, describe, expect, it, vi, vitest } from 'vitest' import { CreateAppInterfacePage } from './create-app-interface-page' import { deployAppLabel } from '../components/labels' -import { useWallet } from '@txnlab/use-wallet-react' +import { useWallet } from '@algorandecosystem/use-wallet-react' import SampleSixAppSpec from '@/tests/test-app-specs/sample-six.arc32.json' import { Arc32AppSpec } from '../data/types' import { selectOption } from '@/tests/utils/select-option' @@ -213,7 +213,7 @@ describe('create-app-interface', () => { describe('when a wallet is not connected', () => { beforeEach(async () => { - const original = await vi.importActual<{ useWallet: () => ReturnType }>('@txnlab/use-wallet-react') + const original = await vi.importActual<{ useWallet: () => ReturnType }>('@algorandecosystem/use-wallet-react') vi.mocked(useWallet).mockImplementation(() => { return { ...original.useWallet(), diff --git a/src/features/common/components/wallet-provider-inner.tsx b/src/features/common/components/wallet-provider-inner.tsx index e5174d8da..063467852 100644 --- a/src/features/common/components/wallet-provider-inner.tsx +++ b/src/features/common/components/wallet-provider-inner.tsx @@ -1,19 +1,18 @@ import { PropsWithChildren } from 'react' import { useSetActiveWalletState } from '@/features/wallet/data/active-wallet' -import { useWallet, WalletManager, WalletProvider } from '@txnlab/use-wallet-react' -import { encodeTransactionRaw, Transaction } from '@algorandfoundation/algokit-utils/transact' +import { useWallet, WalletProvider } from '@algorandecosystem/use-wallet-react' +import { WalletManager } from '@algorandecosystem/use-wallet' type Props = PropsWithChildren<{ walletManager: WalletManager }> function SetActiveWalletState({ children }: PropsWithChildren) { - const { isReady, activeAddress, signTransactions } = useWallet() - useSetActiveWalletState(isReady, activeAddress ?? undefined, async (txnGroup: Transaction[], indexesToSign: number[]) => { - const encodedTxns = txnGroup.map((txn) => encodeTransactionRaw(txn)) - const signResults = await signTransactions(encodedTxns, indexesToSign) - return signResults.filter((r) => r !== null) - }) + const { isReady, activeAddress } = useWallet() + + // No custom signer - let algokit-utils use the default + // Transaction wizard handles all signing + useSetActiveWalletState(isReady, activeAddress ?? undefined) return <>{children} } diff --git a/src/features/common/components/wallet-provider.tsx b/src/features/common/components/wallet-provider.tsx index a5370914f..808498b00 100644 --- a/src/features/common/components/wallet-provider.tsx +++ b/src/features/common/components/wallet-provider.tsx @@ -2,7 +2,7 @@ import { PropsWithChildren, useMemo } from 'react' import { WalletProviderInner } from './wallet-provider-inner' import { defaultKmdWallet, useSelectedKmdWallet } from '@/features/wallet/data/selected-kmd-wallet' import { mainnetId, NetworkConfigWithId } from '@/features/network/data/types' -import { SupportedWallet, WalletId, WalletIdConfig, WalletManager } from '@txnlab/use-wallet-react' +import { SupportedWallet, WalletId, WalletIdConfig, WalletManager } from '@algorandecosystem/use-wallet' import { DialogBodyProps, useDialogForm } from '../hooks/use-dialog-form' import { PromptForm } from './prompt-form' import { loraKmdDevWalletName } from '@/features/fund/utils/kmd' @@ -69,6 +69,15 @@ export function WalletProvider({ networkConfig, children }: Props) { }) } else if ([WalletId.DEFLY, WalletId.PERA, WalletId.EXODUS].includes(id)) { acc.push(id) + } else if (id === WalletId.LIQUID_ALGORAND_ECOSYSTEM) { + acc.push({ + id, + options: { + origin: 'https://liquid-auth-api.pg.nodely.dev', + RTC_config_username: 'liquid-auth', + RTC_config_credential: 'sqmcP4MiTKMT4TGEDSk9jgHY' + }, + }) } else if (id === WalletId.LUTE) { acc.push({ id, diff --git a/src/features/common/data/algo-client.ts b/src/features/common/data/algo-client.ts index bcc6fa467..0082540f7 100644 --- a/src/features/common/data/algo-client.ts +++ b/src/features/common/data/algo-client.ts @@ -1,7 +1,7 @@ import { AlgorandClient, Config } from '@algorandfoundation/algokit-utils' import { networkConfigAtom } from '@/features/network/data' import { settingsStore } from '@/features/settings/data' -import { WalletId } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' import { localnetId, NetworkConfig, NetworkConfigWithId } from '@/features/network/data/types' import { ClientManager } from '@algorandfoundation/algokit-utils/client-manager' diff --git a/src/features/fund/components/localnet-funding.tsx b/src/features/fund/components/localnet-funding.tsx index 21fa0eef0..3c1f4aba3 100644 --- a/src/features/fund/components/localnet-funding.tsx +++ b/src/features/fund/components/localnet-funding.tsx @@ -3,7 +3,8 @@ import { AlgoAmount } from '@algorandfoundation/algokit-utils/amount' import { algorandClient } from '@/features/common/data/algo-client' import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/features/common/components/accordion' import { createLoraKmdDevAccount, loraKmdDevWalletName } from '../utils/kmd' -import { WalletId, useWallet } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' +import { useWallet } from '@algorandecosystem/use-wallet-react' import { useCallback, useState } from 'react' import { Address } from '@/features/accounts/data/types' import { AccountLink } from '@/features/accounts/components/account-link' diff --git a/src/features/layout/pages/layout-page.test.tsx b/src/features/layout/pages/layout-page.test.tsx index 54a7dfb20..1bb1f3691 100644 --- a/src/features/layout/pages/layout-page.test.tsx +++ b/src/features/layout/pages/layout-page.test.tsx @@ -3,7 +3,8 @@ import { fireEvent, render, waitFor } from '@/tests/testing-library' import { describe, expect, it, vi } from 'vitest' import { LayoutPage } from '@/features/layout/pages/layout-page' import { connectWalletLabel, selectAccountLabel, disconnectWalletLabel } from '@/features/wallet/components/connect-wallet-button' -import { NetworkId, Wallet, WalletId, useWallet } from '@txnlab/use-wallet-react' +import { NetworkId, WalletId } from '@algorandecosystem/use-wallet' +import { Wallet, useWallet } from '@algorandecosystem/use-wallet-react' import { AlgodClient } from '@algorandfoundation/algokit-utils/algod-client' describe('when rendering the layout page', () => { @@ -39,7 +40,7 @@ describe('when rendering the layout page', () => { describe('and the wallet is connected', () => { it('the wallet address is shown', async () => { - const original = await vi.importActual<{ useWallet: () => ReturnType }>('@txnlab/use-wallet-react') + const original = await vi.importActual<{ useWallet: () => ReturnType }>('@algorandecosystem/use-wallet-react') vi.mocked(useWallet).mockImplementation(() => { return { ...original.useWallet(), @@ -63,7 +64,7 @@ describe('when rendering the layout page', () => { }) describe('and there is more than one account', () => { it('the account switcher should be shown', async () => { - const original = await vi.importActual<{ useWallet: () => ReturnType }>('@txnlab/use-wallet-react') + const original = await vi.importActual<{ useWallet: () => ReturnType }>('@algorandecosystem/use-wallet-react') vi.mocked(useWallet).mockImplementation(() => { return { ...original.useWallet(), diff --git a/src/features/network/components/create-network-config-form.tsx b/src/features/network/components/create-network-config-form.tsx index 5e3a9a676..eb6d1f9d0 100644 --- a/src/features/network/components/create-network-config-form.tsx +++ b/src/features/network/components/create-network-config-form.tsx @@ -9,7 +9,7 @@ import { CancelButton } from '@/features/forms/components/cancel-button' import { NetworkFormInner } from '@/features/network/components/network-form-inner' import { asStorableServiceConfig } from '@/features/settings/mappers' import { createNetworkConfigFormSchema } from '@/features/settings/form-schemas/create-network-config-form-schema' -import { WalletId } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' import { replaceAll } from '@/utils/replace-all' import { tokenStorageText } from '@/features/network/components/labels' import { Alert } from '@/features/common/components/alert' diff --git a/src/features/network/components/edit-network-config-form.tsx b/src/features/network/components/edit-network-config-form.tsx index 6194a8d78..5247038fd 100644 --- a/src/features/network/components/edit-network-config-form.tsx +++ b/src/features/network/components/edit-network-config-form.tsx @@ -10,7 +10,7 @@ import { editNetworkConfigFormSchema } from '@/features/settings/form-schemas/ed import { NetworkFormInner } from '@/features/network/components/network-form-inner' import { asStorableServiceConfig } from '@/features/settings/mappers' import { NetworkConfigWithId } from '@/features/network/data/types' -import { WalletId } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' import { useRefreshDataProviderToken } from '@/features/common/data' import { Alert } from '@/features/common/components/alert' import { tokenStorageText } from '@/features/network/components/labels' diff --git a/src/features/network/components/network-form-inner.tsx b/src/features/network/components/network-form-inner.tsx index 0c1592d6a..fc6c5c408 100644 --- a/src/features/network/components/network-form-inner.tsx +++ b/src/features/network/components/network-form-inner.tsx @@ -5,7 +5,7 @@ import { useEffect, useMemo, useState } from 'react' import { Fieldset } from '@/features/forms/components/fieldset' import { editNetworkConfigFormSchema } from '@/features/settings/form-schemas/edit-network-config-form-schema' import { createNetworkConfigFormSchema } from '@/features/settings/form-schemas/create-network-config-form-schema' -import { WalletId } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' import { allWalletProviderNames, defaultNetworkConfigs, diff --git a/src/features/network/data/index.ts b/src/features/network/data/index.ts index 8e93ffb50..3d2eb6f07 100644 --- a/src/features/network/data/index.ts +++ b/src/features/network/data/index.ts @@ -1,6 +1,6 @@ import { atom, useAtomValue, useSetAtom } from 'jotai' import { atomWithDefault, atomWithRefresh, atomWithStorage } from 'jotai/utils' -import { WalletId } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' import { useCallback } from 'react' import { NetworkConfig, @@ -21,7 +21,7 @@ import { useDisconnectAllWallets } from '@/features/wallet/hooks/use-disconnect- export { localnetId, testnetId, mainnetId, fnetId, betanetId } from './types' export const localnetWalletIds = [WalletId.KMD, WalletId.MNEMONIC, WalletId.LUTE] -export const nonLocalnetWalletIds = [WalletId.DEFLY, WalletId.PERA, WalletId.EXODUS, WalletId.LUTE] +export const nonLocalnetWalletIds = [WalletId.DEFLY, WalletId.PERA, WalletId.EXODUS, WalletId.LUTE, WalletId.LIQUID_ALGORAND_ECOSYSTEM] export const allWalletProviderNames: Record = { kmd: 'KMD', mnemonic: 'MNEMONIC', @@ -37,6 +37,8 @@ export const allWalletProviderNames: Record = { magic: 'Magic', 'w3-wallet': 'w3-wallet', biatec: 'Biatec', + 'liquid-algorand-ecosystem': 'Liquid Auth', + web3auth: 'Web3Auth', } export const MAINNET_FEE_SINK_ADDRESS = 'Y76M3MSY6DKBRHBL7C3NNDXGS5IIMQVQVUAB6MP4XEMMGVF2QWNPL226CA' diff --git a/src/features/network/data/types.ts b/src/features/network/data/types.ts index de2fa386f..bcdaabe04 100644 --- a/src/features/network/data/types.ts +++ b/src/features/network/data/types.ts @@ -1,5 +1,5 @@ import { Address } from '@/features/accounts/data/types' -import { WalletId } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' export const localnetId = 'localnet' export const testnetId = 'testnet' diff --git a/src/features/settings/components/clear-cache.tsx b/src/features/settings/components/clear-cache.tsx index 5bedca247..4b70868cb 100644 --- a/src/features/settings/components/clear-cache.tsx +++ b/src/features/settings/components/clear-cache.tsx @@ -1,5 +1,5 @@ import { Button } from '@/features/common/components/button' -import { useWallet } from '@txnlab/use-wallet-react' +import { useWallet } from '@algorandecosystem/use-wallet-react' import { useDisconnectWallet } from '@/features/wallet/hooks/use-disconnect-wallet' import { useMemo } from 'react' diff --git a/src/features/settings/form-schemas/create-network-config-form-schema.ts b/src/features/settings/form-schemas/create-network-config-form-schema.ts index 68c4b2146..e5d0b8ac5 100644 --- a/src/features/settings/form-schemas/create-network-config-form-schema.ts +++ b/src/features/settings/form-schemas/create-network-config-form-schema.ts @@ -1,7 +1,7 @@ import { zfd } from 'zod-form-data' import { algoServiceSchema } from '@/features/settings/form-schemas/algo-service-schema' import { z } from 'zod' -import { WalletId } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' export const createNetworkConfigFormSchema = zfd.formData({ name: zfd.text(), diff --git a/src/features/settings/form-schemas/edit-network-config-form-schema.ts b/src/features/settings/form-schemas/edit-network-config-form-schema.ts index 089134de9..ee991cccd 100644 --- a/src/features/settings/form-schemas/edit-network-config-form-schema.ts +++ b/src/features/settings/form-schemas/edit-network-config-form-schema.ts @@ -1,7 +1,7 @@ import { zfd } from 'zod-form-data' import { algoServiceSchema } from '@/features/settings/form-schemas/algo-service-schema' import { z } from 'zod' -import { WalletId } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' export const editNetworkConfigFormSchema = zfd.formData({ indexer: algoServiceSchema, diff --git a/src/features/transaction-wizard/components/transactions-builder.tsx b/src/features/transaction-wizard/components/transactions-builder.tsx index 9ab2469f8..907a15b1c 100644 --- a/src/features/transaction-wizard/components/transactions-builder.tsx +++ b/src/features/transaction-wizard/components/transactions-builder.tsx @@ -5,7 +5,7 @@ import { useCallback, useMemo, useState } from 'react' import { DialogBodyProps, useDialogForm } from '@/features/common/hooks/use-dialog-form' import { AsyncActionButton, Button } from '@/features/common/components/button' import { TransactionBuilder } from './transaction-builder' -import { useWallet } from '@txnlab/use-wallet-react' +import { useWallet } from '@algorandecosystem/use-wallet-react' import { invariant } from '@/utils/invariant' import { BuildableTransactionType, diff --git a/src/features/transaction-wizard/data/common.ts b/src/features/transaction-wizard/data/common.ts index 57e881f01..5fccfb693 100644 --- a/src/features/transaction-wizard/data/common.ts +++ b/src/features/transaction-wizard/data/common.ts @@ -156,6 +156,8 @@ export const commonSchema = { export const commonFormData = zfd.formData(commonSchema) +const nullSigner = makeEmptyTransactionSigner() + export const buildComposer = async (transactions: BuildTransactionResult[]) => { const algokitTxns: Transaction[] = [] @@ -165,12 +167,10 @@ export const buildComposer = async (transactions: BuildTransactionResult[]) => { } const composer = algorandClient.newGroup() - algokitTxns.forEach((txn) => composer.addTransaction(txn)) + algokitTxns.forEach((txn) => composer.addTransaction(txn, nullSigner)) return composer } -const nullSigner = makeEmptyTransactionSigner() - export const buildComposerWithEmptySignatures = async (transactions: BuildTransactionResult[]) => { const algokitTxns: Transaction[] = [] diff --git a/src/features/transaction-wizard/transaction-wizard-page.test.tsx b/src/features/transaction-wizard/transaction-wizard-page.test.tsx index 89620d9c1..bb367a232 100644 --- a/src/features/transaction-wizard/transaction-wizard-page.test.tsx +++ b/src/features/transaction-wizard/transaction-wizard-page.test.tsx @@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, vitest, it, vi } from 'vitest' import { algorandFixture } from '@algorandfoundation/algokit-utils/testing' import { executeComponentTest } from '@/tests/test-component' import { fireEvent, render, waitFor, within } from '@/tests/testing-library' -import { useWallet } from '@txnlab/use-wallet-react' +import { useWallet } from '@algorandecosystem/use-wallet-react' import { algo } from '@algorandfoundation/algokit-utils' import { sendButtonLabel, simulateButtonLabel, transactionTypeLabel, TransactionWizardPage } from './transaction-wizard-page' import { selectOption } from '@/tests/utils/select-option' @@ -20,7 +20,7 @@ describe('transaction-wizard-page', () => { describe('when a wallet is not connected', () => { beforeEach(async () => { - const original = await vi.importActual<{ useWallet: () => ReturnType }>('@txnlab/use-wallet-react') + const original = await vi.importActual<{ useWallet: () => ReturnType }>('@algorandecosystem/use-wallet-react') vi.mocked(useWallet).mockImplementation(() => { return { ...original.useWallet(), diff --git a/src/features/transaction-wizard/transaction-wizard-page.tsx b/src/features/transaction-wizard/transaction-wizard-page.tsx index 900d7209c..383a4ce99 100644 --- a/src/features/transaction-wizard/transaction-wizard-page.tsx +++ b/src/features/transaction-wizard/transaction-wizard-page.tsx @@ -1,10 +1,9 @@ import { useCallback, useState } from 'react' import { PageTitle } from '../common/components/page-title' import { SimulateResult, transactionGroupLabel, TransactionsBuilder } from './components/transactions-builder' -import { buildComposer } from './data/common' import { asTransactionFromSendResult } from '../transactions/data/send-transaction-result' import { asTransactionsGraphData } from '../transactions-graph/mappers' -import { BuildTransactionResult } from './models' +import { BuildTransactionResult, BuildableTransactionType } from './models' import { SendTransactionResults } from '@algorandfoundation/algokit-utils/transaction' import { SimulateResponse } from '@algorandfoundation/algokit-utils/algod-client' import { AppCallTransaction, TransactionType } from '../transactions/models' @@ -13,6 +12,9 @@ import { useTitle } from '@/utils/use-title' import { PageLoader } from '../common/components/page-loader' import { useLoadableSearchParamsTransactions } from '../transactions/data/use-loadable-search-params-transaction' import { RenderLoadable } from '../common/components/render-loadable' +import { useWallet } from '@algorandecosystem/use-wallet-react' +import algosdk from 'algosdk' +import { invariant } from '@/utils/invariant' export const transactionWizardPageTitle = 'Transaction Wizard' export const transactionTypeLabel = 'Transaction type' @@ -22,6 +24,7 @@ export const simulateButtonLabel = 'Simulate' export function TransactionWizardPage() { const [sendResults, setSendResults] = useState(undefined) const loadableSearchParamsTransactions = useLoadableSearchParamsTransactions() + const { transactionSigner, activeAddress, activeWallet, algodClient } = useWallet() useTitle('Transaction Wizard') const renderTransactionResults = useCallback((result: SendTransactionResults, simulateResponse?: SimulateResponse) => { @@ -35,13 +38,290 @@ export function TransactionWizardPage() { }) }, []) - const sendTransactions = useCallback( + const sendTransactionsCallback = useCallback( async (transactions: BuildTransactionResult[]) => { - const composer = await buildComposer(transactions) - const result = await composer.send() - renderTransactionResults(result) + invariant(activeAddress, 'No active address available') + invariant(algodClient, 'No algod client available') + + console.info('[Wallet] Using wallet:', activeWallet?.id) + console.info('[Wallet] Processing', transactions.length, 'transactions from wizard') + + // Get suggested params from algod + const suggestedParams = await algodClient.getTransactionParams().do() + + // Create algosdk transactions directly from the wizard data + // This matches the working example pattern + console.info('[Wallet] Creating algosdk transactions...') + const algosdkTxns: algosdk.Transaction[] = [] + + for (const txn of transactions) { + const rawTxn = txn as any + + // Handle different transaction types + if (txn.type === BuildableTransactionType.Payment) { + // Payment transaction + const sender = rawTxn.sender?.resolvedAddress || activeAddress + const receiver = rawTxn.receiver?.resolvedAddress || activeAddress + const amount = Number(rawTxn.amount || 0) + + algosdkTxns.push( + algosdk.makePaymentTxnWithSuggestedParamsFromObject({ + sender, + receiver, + amount, + note: rawTxn.note ? new TextEncoder().encode(rawTxn.note) : undefined, + suggestedParams, + }) + ) + } else if (txn.type === BuildableTransactionType.AppCall) { + // App call transaction + const sender = rawTxn.sender?.resolvedAddress || activeAddress + const appIndex = Number(rawTxn.applicationId || 0) + const onComplete = Number(rawTxn.onComplete ?? 0) + + algosdkTxns.push( + algosdk.makeApplicationCallTxnFromObject({ + sender, + appIndex, + onComplete: onComplete as algosdk.OnApplicationComplete, + appArgs: rawTxn.args, + accounts: rawTxn.accounts, + foreignApps: rawTxn.foreignApps?.map(Number), + foreignAssets: rawTxn.foreignAssets?.map(Number), + suggestedParams, + }) + ) + } else if (txn.type === BuildableTransactionType.AssetTransfer) { + // Asset transfer + const sender = rawTxn.sender?.resolvedAddress || activeAddress + const assetIndex = Number(rawTxn.asset?.id || 0) + const receiver = rawTxn.receiver?.resolvedAddress || activeAddress + const amount = Number(rawTxn.amount || 0) + + algosdkTxns.push( + algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject({ + sender, + assetIndex, + receiver, + amount, + suggestedParams, + }) + ) + } else { + // Fallback for unsupported types - create a simple 0-amount payment + console.warn('[Wallet] Unsupported transaction type:', txn.type, '- creating placeholder transaction') + algosdkTxns.push( + algosdk.makePaymentTxnWithSuggestedParamsFromObject({ + sender: activeAddress, + receiver: activeAddress, + amount: 0, + suggestedParams, + }) + ) + } + } + + if (algosdkTxns.length === 0) { + throw new Error('No transactions to send') + } + + console.info('[Wallet] Created', algosdkTxns.length, 'algosdk transactions') + + // Sign using transactionSigner (receives algosdk Transaction[] directly) + const indexesToSign = Array.from({ length: algosdkTxns.length }, (_, i) => i) + console.info('[Wallet] Signing', algosdkTxns.length, 'transactions with transactionSigner...') + const signResults = await transactionSigner(algosdkTxns, indexesToSign) + + // Check we got signatures + const signedTxns = signResults.filter((r): r is Uint8Array => r !== null) + console.info('[Wallet] Sent', algosdkTxns.length, 'txns to wallet, got', signedTxns.length, 'signed back') + + if (signedTxns.length === 0) { + throw new Error('No signatures received') + } + + // Detect if this is a Falcon24 signature based on size + const firstSignedTxn = signedTxns[0] + const isFalcon24 = firstSignedTxn && firstSignedTxn.length > 1000 + + console.info('[Wallet] First txn size:', firstSignedTxn?.length, 'bytes') + console.info('[Wallet] Is Falcon24:', isFalcon24) + + if (isFalcon24) { + // If wallet returned multiple txns, log each one + if (signedTxns.length > 1) { + console.info('[Falcon24] Wallet returned', signedTxns.length, 'separate transactions:') + signedTxns.forEach((txn, i) => { + try { + const decoded = algosdk.decodeSignedTransaction(txn) + console.info(` [Falcon24] Txn ${i}: type=${decoded.txn.type}, size=${txn.length} bytes, hasGroup=${!!decoded.txn.group}`) + } catch { + console.info(` [Falcon24] Txn ${i}: size=${txn.length} bytes (could not decode)`) + } + }) + } + + // Try to decode the first one to see what's inside + try { + const decoded = algosdk.decodeSignedTransaction(firstSignedTxn) + console.info('[Falcon24] Decoded txn type:', decoded.txn.type) + console.info('[Falcon24] Decoded txn has group:', !!decoded.txn.group) + if (decoded.txn.group) { + console.info('[Falcon24] Group ID:', Buffer.from(decoded.txn.group).toString('base64')) + } + } catch (e) { + console.info('[Falcon24] Could not decode as single txn:', e) + } + + // Send all transactions to the node + // If wallet returned multiple, concatenate them; otherwise send the single payload + let payloadToSend: Uint8Array + if (signedTxns.length === 1) { + payloadToSend = firstSignedTxn + console.info('[Falcon24] Sending single payload of', firstSignedTxn.length, 'bytes') + } else { + // Concatenate all signed transactions + const totalLength = signedTxns.reduce((sum, txn) => sum + txn.length, 0) + payloadToSend = new Uint8Array(totalLength) + let offset = 0 + for (const txn of signedTxns) { + payloadToSend.set(txn, offset) + offset += txn.length + } + console.info('[Falcon24] Sending concatenated payload:', signedTxns.length, 'txns,', totalLength, 'bytes') + } + + const sendResponse = await algodClient.sendRawTransaction(payloadToSend).do() + const txId = typeof sendResponse === 'string' ? sendResponse : (sendResponse as unknown as { txid: string }).txid + console.info('[Falcon24] Payload sent, txId:', txId) + + // Wait for confirmation + const confirmation = await algosdk.waitForConfirmation(algodClient, txId, 4) + console.info('[Falcon24] Confirmed in round:', confirmation.confirmedRound) + + // Extract info from the signed payload + const firstDecodedTxn = algosdk.decodeSignedTransaction(firstSignedTxn) + const groupId = firstDecodedTxn?.txn?.group + ? Buffer.from(firstDecodedTxn.txn.group).toString('base64') + : undefined + + // Create confirmations with genesis info from decoded transactions + const confirmations: any[] = [] + const txIds: string[] = [] + const decodedTransactions: algosdk.Transaction[] = [] + + // Decode each signed transaction to get its details + for (let i = 0; i < signedTxns.length; i++) { + const signedTxn = signedTxns[i] + if (!signedTxn) continue + + try { + const decoded = algosdk.decodeSignedTransaction(signedTxn) + const currentTxId = decoded.txn.txID() + txIds.push(currentTxId) + decodedTransactions.push(decoded.txn) + + confirmations.push({ + ...confirmation, + txn: { + txn: { + ...decoded.txn, + txId: () => currentTxId, + genesisHash: decoded.txn.genesisHash, + genesisId: decoded.txn.genesisID, + } + } + }) + } catch { + // Fallback: use the main confirmation + txIds.push(txId) + decodedTransactions.push(algosdkTxns[0]) + confirmations.push({ + ...confirmation, + txn: { + txn: { + txId: () => txId, + genesisHash: algosdkTxns[0]?.genesisHash, + genesisId: algosdkTxns[0]?.genesisID, + } + } + }) + } + } + + // Create result with confirmations for UI rendering + const result: any = { + groupId: groupId, + txIds: txIds, + transactions: decodedTransactions, + confirmations: confirmations, + } + + renderTransactionResults(result) + } else { + // Standard Ed25519 flow + console.info('[Ed25519] Sending transactions...') + console.info('[Ed25519] Total transactions to send:', signedTxns.length) + + // For Ed25519, we can also send as a group for better consistency + // Concatenate all signed transactions into a single byte array + const totalLength = signedTxns.reduce((sum, txn) => sum + txn.length, 0) + const concatenatedTxns = new Uint8Array(totalLength) + let offset = 0 + for (const txn of signedTxns) { + concatenatedTxns.set(txn, offset) + offset += txn.length + } + + console.info(`[Ed25519] Sending ${signedTxns.length} transactions as group (${totalLength} bytes)...`) + + // Send all transactions together in a single call + const sendResponse = await algodClient.sendRawTransaction(concatenatedTxns).do() + const txId = typeof sendResponse === 'string' ? sendResponse : (sendResponse as unknown as { txid: string }).txid + console.info('[Ed25519] Group sent, first txId:', txId) + + // Wait for confirmation of the first transaction + const confirmation = await algosdk.waitForConfirmation(algodClient, txId, 4) + console.info('[Ed25519] First transaction confirmed in round:', confirmation.confirmedRound) + + // Create confirmations for all transactions + const confirmations: any[] = [] + const txIds: string[] = [] + + for (let i = 0; i < algosdkTxns.length; i++) { + const txn = algosdkTxns[i] + const signedTxn = signResults[i] + if (!signedTxn) continue + + const currentTxId = signedTxn ? algosdk.decodeSignedTransaction(signedTxn).txn.txID() : undefined + if (currentTxId) { + txIds.push(currentTxId) + } + + const confirmationCopy: any = { ...confirmation } + confirmationCopy.txn = { + txn: { + ...((confirmation as any).txn?.txn || {}), + genesisHash: txn.genesisHash, + genesisId: txn.genesisID, + txId: () => currentTxId || txId + } + } + confirmations.push(confirmationCopy) + } + + // Create result with confirmations for UI rendering + const result: any = { + groupId: undefined, + txIds: txIds, + transactions: algosdkTxns, + confirmations: confirmations, + } + + renderTransactionResults(result) + } }, - [renderTransactionResults] + [transactionSigner, activeAddress, activeWallet, algodClient, renderTransactionResults] ) const renderSimulateResult = useCallback( @@ -66,7 +346,7 @@ export function TransactionWizardPage() { {transactionGroupLabel}} - onSendTransactions={sendTransactions} + onSendTransactions={sendTransactionsCallback} onSimulated={renderSimulateResult} onReset={reset} /> diff --git a/src/features/wallet/components/connect-wallet-button.tsx b/src/features/wallet/components/connect-wallet-button.tsx index 4d1bd8bab..908e9646a 100644 --- a/src/features/wallet/components/connect-wallet-button.tsx +++ b/src/features/wallet/components/connect-wallet-button.tsx @@ -1,7 +1,8 @@ import { Button } from '@/features/common/components/button' import { cn } from '@/features/common/utils' import { Dialog, DialogContent, DialogHeader, DialogTitle, SmallSizeDialogBody } from '@/features/common/components/dialog' -import { WalletAccount, WalletId, Wallet, useWallet } from '@txnlab/use-wallet-react' +import { WalletAccount, WalletId } from '@algorandecosystem/use-wallet' +import { Wallet, useWallet } from '@algorandecosystem/use-wallet-react' import { ellipseAddress } from '@/utils/ellipse-address' import { AccountLink } from '@/features/accounts/components/account-link' import { Loader2 as Loader, CircleMinus, Wallet as WalletIcon } from 'lucide-react' diff --git a/src/features/wallet/components/kmd-wallet-connect-button.tsx b/src/features/wallet/components/kmd-wallet-connect-button.tsx index 37be98093..2c6e2137d 100644 --- a/src/features/wallet/components/kmd-wallet-connect-button.tsx +++ b/src/features/wallet/components/kmd-wallet-connect-button.tsx @@ -1,5 +1,5 @@ import { Button } from '@/features/common/components/button' -import { Wallet } from '@txnlab/use-wallet-react' +import { Wallet } from '@algorandecosystem/use-wallet-react' import { cn } from '@/features/common/utils' import { Loader2 as Loader, Wallet as WalletIcon } from 'lucide-react' import { defaultKmdWallet, selectedKmdWalletAtom } from '../data/selected-kmd-wallet' diff --git a/src/features/wallet/components/wallet-connect-button.tsx b/src/features/wallet/components/wallet-connect-button.tsx index dca01a112..07414b9c6 100644 --- a/src/features/wallet/components/wallet-connect-button.tsx +++ b/src/features/wallet/components/wallet-connect-button.tsx @@ -1,5 +1,6 @@ import { Button } from '@/features/common/components/button' -import { WalletId, Wallet } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' +import { Wallet } from '@algorandecosystem/use-wallet-react' import { cn } from '@/features/common/utils' import { Wallet as WalletIcon } from 'lucide-react' diff --git a/src/features/wallet/data/active-wallet.ts b/src/features/wallet/data/active-wallet.ts index b40831a52..f6e13458e 100644 --- a/src/features/wallet/data/active-wallet.ts +++ b/src/features/wallet/data/active-wallet.ts @@ -8,6 +8,7 @@ import { atomEffect } from 'jotai-effect' import { TransactionSigner } from '@algorandfoundation/algokit-utils/transact' const activeWalletAddressAtom = atom | (Address | undefined)>(new Promise
(() => {})) + export const activeWalletAccountAtom = atomWithRefresh>(async (get) => { const activeWalletAddress = await get(activeWalletAddressAtom) if (activeWalletAddress) { @@ -17,12 +18,14 @@ export const activeWalletAccountAtom = atomWithRefresh { +export const useSetActiveWalletState = (isReady: boolean, activeAddress: string | undefined, signer?: TransactionSigner) => { const setActiveWalletAddress = useSetAtom(activeWalletAddressAtom) useEffect(() => { if (isReady) { setActiveWalletAddress(activeAddress) - algorandClient.setDefaultSigner(signer) + if (signer) { + algorandClient.setDefaultSigner(signer) + } } }, [setActiveWalletAddress, activeAddress, signer, isReady]) } diff --git a/src/features/wallet/hooks/use-disconnect-all-wallets.ts b/src/features/wallet/hooks/use-disconnect-all-wallets.ts index 6ad2cf797..2b161e64f 100644 --- a/src/features/wallet/hooks/use-disconnect-all-wallets.ts +++ b/src/features/wallet/hooks/use-disconnect-all-wallets.ts @@ -1,4 +1,4 @@ -import { useWallet } from '@txnlab/use-wallet-react' +import { useWallet } from '@algorandecosystem/use-wallet-react' import { useSetAtom } from 'jotai' import { useCallback } from 'react' import { selectedKmdWalletAtom } from '../data/selected-kmd-wallet' diff --git a/src/features/wallet/hooks/use-disconnect-wallet.ts b/src/features/wallet/hooks/use-disconnect-wallet.ts index e32240ec0..a0fc6132c 100644 --- a/src/features/wallet/hooks/use-disconnect-wallet.ts +++ b/src/features/wallet/hooks/use-disconnect-wallet.ts @@ -1,4 +1,5 @@ -import { Wallet, WalletId } from '@txnlab/use-wallet-react' +import { WalletId } from '@algorandecosystem/use-wallet' +import { Wallet } from '@algorandecosystem/use-wallet-react' import { useCallback } from 'react' import { selectedKmdWalletAtom } from '../data/selected-kmd-wallet' import { useSetAtom } from 'jotai' diff --git a/src/tests/setup/mocks/index.ts b/src/tests/setup/mocks/index.ts index b17b3a00c..e291735ef 100644 --- a/src/tests/setup/mocks/index.ts +++ b/src/tests/setup/mocks/index.ts @@ -1,5 +1,6 @@ import { vi } from 'vitest' -import { NetworkId, Wallet, WalletId, useWallet } from '@txnlab/use-wallet-react' +import { NetworkId, WalletId } from '@algorandecosystem/use-wallet' +import { Wallet, useWallet } from '@algorandecosystem/use-wallet-react' import { AlgodClient } from '@algorandfoundation/algokit-utils/algod-client' vi.mock('react-router-dom', async () => ({ @@ -15,8 +16,8 @@ vi.mock('@algorandfoundation/algokit-utils', async () => ({ lookupTransactionById: vi.fn(), })) -vi.mock('@txnlab/use-wallet-react', async () => { - const original = await vi.importActual<{ useWallet: () => ReturnType }>('@txnlab/use-wallet-react') +vi.mock('@algorandecosystem/use-wallet-react', async () => { + const original = await vi.importActual<{ useWallet: () => ReturnType }>('@algorandecosystem/use-wallet-react') return { ...original, useWallet: vi.fn().mockImplementation(() => { diff --git a/src/tests/test-wallet-provider.tsx b/src/tests/test-wallet-provider.tsx index 60ff80101..70e201c5c 100644 --- a/src/tests/test-wallet-provider.tsx +++ b/src/tests/test-wallet-provider.tsx @@ -1,5 +1,5 @@ import { mainnetId, NetworkConfigWithId } from '@/features/network/data/types' -import { WalletManager } from '@txnlab/use-wallet' +import { WalletManager } from '@algorandecosystem/use-wallet' import { PropsWithChildren, useMemo } from 'react' import { WalletProviderInner } from '@/features/common/components/wallet-provider-inner' diff --git a/src/tests/utils/set-wallet-address-and-signer.ts b/src/tests/utils/set-wallet-address-and-signer.ts index d1af7974a..46a480cf9 100644 --- a/src/tests/utils/set-wallet-address-and-signer.ts +++ b/src/tests/utils/set-wallet-address-and-signer.ts @@ -1,12 +1,12 @@ import { algorandFixture } from '@algorandfoundation/algokit-utils/testing' import { vi } from 'vitest' -import { useWallet } from '@txnlab/use-wallet-react' +import { useWallet } from '@algorandecosystem/use-wallet-react' import { decodeTransaction } from '@algorandfoundation/algokit-utils/transact' export const setWalletAddressAndSigner = async (localnet: ReturnType) => { const { testAccount } = localnet.context - const original = await vi.importActual<{ useWallet: () => ReturnType }>('@txnlab/use-wallet-react') + const original = await vi.importActual<{ useWallet: () => ReturnType }>('@algorandecosystem/use-wallet-react') vi.mocked(useWallet).mockImplementation(() => { return { ...original.useWallet(), diff --git a/vite.config.ts b/vite.config.ts index 33a08aa63..67daaa286 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -51,5 +51,17 @@ export default defineConfig(({ mode }) => ({ alias: { '@': path.resolve(__dirname, './src'), }, + preserveSymlinks: true, + }, + optimizeDeps: { + include: [ + '@tanstack/react-store', + '@algorandecosystem/use-wallet', + '@algorandecosystem/use-wallet-react', + 'algosdk', + '@blockshake/defly-connect', + '@perawallet/connect', + 'lute-connect', + ], }, }))