diff --git a/apps/taquito-test-dapp/package.json b/apps/taquito-test-dapp/package.json index fb17e5acbe..0453ae2f0b 100644 --- a/apps/taquito-test-dapp/package.json +++ b/apps/taquito-test-dapp/package.json @@ -28,7 +28,9 @@ "@taquito/beacon-wallet": "^15.0.0", "@taquito/taquito": "^15.0.0", "@taquito/utils": "^15.0.0", + "@taquito/wallet-connect-2": "^15.0.0", "buffer": "^6.0.3", + "svelte-modals": "^2.0.0-beta.2", "svelte-select": "^4.4.7", "vite-compatible-readable-stream": "^3.6.1" }, diff --git a/apps/taquito-test-dapp/src/App.svelte b/apps/taquito-test-dapp/src/App.svelte index 89da2c6f33..5d6ae87d29 100644 --- a/apps/taquito-test-dapp/src/App.svelte +++ b/apps/taquito-test-dapp/src/App.svelte @@ -4,7 +4,7 @@ import { NetworkType } from "@airgap/beacon-sdk"; import Select from "svelte-select"; import { rpcUrl } from "./config"; - import store from "./store"; + import store, { SDK } from "./store"; import Layout from "./Layout.svelte"; import TestContainer from "./lib/TestContainer.svelte"; @@ -42,14 +42,6 @@ store.updateTezos(new TezosToolkit(rpcUrl.mainnet)); store.updateNetworkType(NetworkType.MAINNET); break; - case "hangzhounet": - store.updateTezos(new TezosToolkit(rpcUrl.hangzhounet)); - store.updateNetworkType(NetworkType.HANGZHOUNET); - break; - case "ithacanet": - store.updateTezos(new TezosToolkit(rpcUrl.ithacanet)); - store.updateNetworkType(NetworkType.ITHACANET); - break; case "ghostnet": store.updateTezos(new TezosToolkit(rpcUrl.ghostnet)); store.updateNetworkType(NetworkType.GHOSTNET); @@ -149,6 +141,18 @@ margin: 10px 0px; } + .sdk { + border: 1px solid; + border-radius: 10px; + display: flex; + flex-direction: column; + align-items: flex-start; + padding: 20px; + grid-row-gap: 10px; + align-items: center; + width: 100%; + } + button { width: 100%; justify-content: center; @@ -195,15 +199,50 @@
(use Chrome for a better experience)
{/if}
- +
+ Connect using beacon sdk + + +
+
+ Connect using Wallet Connect 2 + +
diff --git a/apps/taquito-test-dapp/src/lib/ModalActivePairing.svelte b/apps/taquito-test-dapp/src/lib/ModalActivePairing.svelte new file mode 100644 index 0000000000..86c1060bd8 --- /dev/null +++ b/apps/taquito-test-dapp/src/lib/ModalActivePairing.svelte @@ -0,0 +1,79 @@ + + + + +{#if isOpen} + +{/if} diff --git a/apps/taquito-test-dapp/src/lib/TestContainer.svelte b/apps/taquito-test-dapp/src/lib/TestContainer.svelte index d098362361..5e5fb540b8 100644 --- a/apps/taquito-test-dapp/src/lib/TestContainer.svelte +++ b/apps/taquito-test-dapp/src/lib/TestContainer.svelte @@ -4,6 +4,7 @@ import type { TestSettings, TestResult } from "../types"; import { shortenHash } from "../utils"; import { NetworkType } from "@airgap/beacon-sdk"; + import { BeaconWallet } from "@taquito/beacon-wallet"; let test: TestSettings | undefined; let executionTime = 0; @@ -12,6 +13,7 @@ let opHash = ""; let input = { text: "", fee: 400, storageLimit: 400, gasLimit: 1320 }; let testResult: { id: string; title: string; body: any }; + let error: Error | undefined; const run = async () => { success = undefined; @@ -63,7 +65,8 @@ }; } } else { - throw "Error"; + error = result.error; + throw result.error; } } catch (error) { console.log(error); @@ -75,7 +78,9 @@ }; const switchAccount = async () => { - await $store.wallet.clearActiveAccount(); + if($store.wallet instanceof BeaconWallet){ + await $store.wallet.clearActiveAccount(); + } store.updateUserAddress(undefined); store.updateUserBalance(undefined); store.updateWallet(undefined); @@ -274,7 +279,9 @@ {#if test.documentation}
- Learn more about {test.keyword} with Taquito + Learn more about {test.keyword} with Taquito
{/if} @@ -369,6 +376,15 @@

Test failed sentiment_very_dissatisfied

+ {#if error} +
+ {#if error instanceof Error} + {error} + {:else} + {JSON.stringify(error)} + {/if} +
+ {/if} {/if}
@@ -383,7 +399,9 @@
{#if test.documentation}
- Learn more about {test.keyword} with Taquito + Learn more about {test.keyword} with Taquito
{/if} {/if} diff --git a/apps/taquito-test-dapp/src/lib/Wallet.svelte b/apps/taquito-test-dapp/src/lib/Wallet.svelte index 648bf5aff1..b77becbf1f 100644 --- a/apps/taquito-test-dapp/src/lib/Wallet.svelte +++ b/apps/taquito-test-dapp/src/lib/Wallet.svelte @@ -3,111 +3,213 @@ import { fly } from "svelte/transition"; import { TezosToolkit } from "@taquito/taquito"; import { BeaconWallet } from "@taquito/beacon-wallet"; - // import { BeaconEvent, defaultEventCallbacks } from "@airgap/beacon-sdk"; - import { NetworkType } from "@airgap/beacon-sdk"; - import store from "../store"; + import store, { SDK } from "../store"; import { formatTokenAmount, shortenHash } from "../utils"; - import { defaultMatrixNode, rpcUrl, defaultNetworkType } from "../config"; + import { defaultMatrixNode, rpcUrl } from "../config"; import type { TezosAccountAddress } from "../types"; + import { WalletConnect2, PermissionScopeMethods, NetworkType as NetworkTypeWc2 } from "@taquito/wallet-connect-2"; + import { Modals, closeModal, openModal } from "svelte-modals"; + import ModalActivePairing from "./ModalActivePairing.svelte"; + import type { NetworkType as NetworkTypeBeacon } from "@airgap/beacon-sdk"; let showDialog = false; let connectedWallet = ""; - const createNewWallet = () => { - return new BeaconWallet( - $store.disableDefaultEvents - ? { - name: "Taquito Test Dapp", - matrixNodes: [defaultMatrixNode] as any, - preferredNetwork: $store.networkType, - // disableDefaultEvents: true // Disable all events / UI. This also disables the pairing alert. - // eventHandlers: { - // // To keep the pairing alert, we have to add the following default event handlers back - // [BeaconEvent.PAIR_INIT]: { - // handler: defaultEventCallbacks.PAIR_INIT - // }, - // [BeaconEvent.PAIR_SUCCESS]: { - // handler: defaultEventCallbacks.PAIR_SUCCESS - // } - // } - } - : { - name: "Taquito Test Dapp", - matrixNodes: [defaultMatrixNode] as any, - preferredNetwork: $store.networkType, - } + const selectExistingPairing = (wallet: WalletConnect2, existingPairing: any[]) => { + openModal( + ModalActivePairing, + { + title: "Select available pairing", + options: existingPairing, + }, + { + on: { + select: async (event) => { + closeModal(); + const topic = event.detail === "new_pairing" ? undefined : event.detail.topic; + await requestPermissionWc2(wallet, topic); + }, + }, + } ); }; + const createNewBeaconWallet = () => { + return new BeaconWallet({ + name: "Taquito Test Dapp", + matrixNodes: [defaultMatrixNode] as any, + preferredNetwork: $store.networkType as NetworkTypeBeacon, + }); + }; + + const createNewWalletConnect2 = async () => { + const wallet = await WalletConnect2.init({ + logger: "debug", + projectId: "861613623da99d7285aaad8279a87ee9", // Your Project ID gives you access to WalletConnect Cloud. + metadata: { + name: "Taquito Test Dapp", + description: "Test Taquito with WalletConnect2", + icons: [], + url: "", + }, + }); + wallet.signClient.on("session_ping", ({ id, topic }) => { + console.log("session_ping in test dapp", id, topic); + }); + wallet.signClient.on("session_delete", ({ topic }) => { + console.log("EVEN: session_delete", topic); + if (!wallet.isActiveSession()) { + resetApp(); + } + }); + wallet.signClient.on("session_update", async ({ topic }) => { + console.log("EVEN: session_update", topic); + const allAccounts = wallet.getAccounts(); + await updateStore(wallet, allAccounts); + }); + return wallet; + }; + + const requestPermissionWc2 = async (wallet: WalletConnect2, pairingTopic?: string) => { + await wallet.requestPermissions({ + permissionScope: { + networks: [$store.networkType as NetworkTypeWc2], + events: [], + methods: [PermissionScopeMethods.OPERATION_REQUEST, PermissionScopeMethods.SIGN], + }, + pairingTopic, + registryUrl: "https://www.tezos.help/wcdata/" + }); + const allAccounts = wallet.getAccounts(); + await updateStore(wallet, allAccounts); + }; + + const connectWalletWithExistingSession = async (sessionId: string) => { + const newWallet = await createNewWalletConnect2(); + newWallet.configureWithExistingSessionKey(sessionId); + const allAccounts = newWallet.getAccounts(); + await updateStore(newWallet, allAccounts); + }; + const connectWallet = async () => { - const wallet = (() => { - if (!$store.wallet) { - return createNewWallet(); - } else { - return $store.wallet; + if (!$store.wallet) { + if ($store.sdk === SDK.BEACON) { + const newWallet = createNewBeaconWallet(); + await newWallet.requestPermissions({ + network: { + type: $store.networkType as NetworkTypeBeacon, + rpcUrl: rpcUrl[$store.networkType], + }, + }); + + const peers = await newWallet.client.getPeers(); + connectedWallet = peers[0].name; + await updateStore(newWallet); + } else if ($store.sdk === SDK.WC2) { + const newWallet = await createNewWalletConnect2(); + const existingPairing = newWallet.getAvailablePairing(); + if (existingPairing.length > 0) { + selectExistingPairing(newWallet, existingPairing); + } else { + await requestPermissionWc2(newWallet); + } } - })(); + } else { + return $store.wallet; + } + }; - try { - await wallet.requestPermissions({ - network: { - type: $store.networkType, - rpcUrl: rpcUrl[$store.networkType], - }, - }); + const updateUserBalance = async (userAddress: string) => { + const balance = await $store.Tezos.tz.getBalance(userAddress); + if (balance) { + store.updateUserBalance(balance.toNumber()); + } + }; - const userAddress = (await wallet.getPKH()) as TezosAccountAddress; + const updateStore = async (wallet: BeaconWallet | WalletConnect2, allAccounts?: string[]) => { + try { + store.updateWallet(wallet); + let userAddress: TezosAccountAddress; + if (allAccounts) { + if (allAccounts.length > 1) { + userAddress = allAccounts.shift() as TezosAccountAddress; + store.updateAvailableAccounts(allAccounts); + } else { + store.updateAvailableAccounts([]); + userAddress = allAccounts[0] as TezosAccountAddress; + } + } else { + userAddress = (await wallet.getPKH()) as TezosAccountAddress; + } store.updateUserAddress(userAddress); + if (wallet instanceof WalletConnect2) { + wallet.setActiveAccount(userAddress); + wallet.setActiveNetwork($store.networkType as any); + } const Tezos = new TezosToolkit(rpcUrl[$store.networkType]); Tezos.setWalletProvider(wallet); store.updateTezos(Tezos); - const balance = await Tezos.tz.getBalance(userAddress); - if (balance) { - store.updateUserBalance(balance.toNumber()); - } - - store.updateWallet(wallet); - - const peers = await wallet.client.getPeers(); - connectedWallet = peers[0].name; + await updateUserBalance(userAddress); } catch (err) { console.error(err); } }; - const disconnectWallet = async () => { - await $store.wallet.clearActiveAccount(); + const resetApp = async () => { store.updateUserAddress(undefined); store.updateUserBalance(undefined); store.updateWallet(undefined); store.updateSelectedTest(undefined); + store.updateTests([]); + store.updateAvailableAccounts(undefined); }; - onMount(async () => { - store.updateNetworkType(defaultNetworkType); - - const wallet = createNewWallet(); - store.updateWallet(wallet); - const activeAccount = await wallet.client.getActiveAccount(); - if (activeAccount) { - const userAddress = (await wallet.getPKH()) as TezosAccountAddress; - store.updateUserAddress(userAddress); + const disconnectWallet = async () => { + if ($store.wallet instanceof BeaconWallet) { + await $store.wallet.clearActiveAccount(); + } else if ($store.wallet instanceof WalletConnect2) { + await $store.wallet.disconnect(); + } + resetApp(); + }; - const Tezos = new TezosToolkit(rpcUrl[$store.networkType]); - Tezos.setWalletProvider(wallet); - store.updateTezos(Tezos); + const switchActiveAccount = (newActiveAccount: string) => { + const currentPkh = $store.userAddress; + const availablePkh = $store.availableAccounts; + const index = availablePkh.indexOf(newActiveAccount, 0); + if (index > -1) { + availablePkh.splice(index, 1); + } + availablePkh.push(currentPkh); + store.updateAvailableAccounts(availablePkh); + store.updateUserAddress(newActiveAccount); + if ($store.wallet instanceof WalletConnect2) { + $store.wallet.setActiveAccount(newActiveAccount); + } + updateUserBalance(newActiveAccount); + }; - const balance = await Tezos.tz.getBalance(userAddress); - if (balance) { - store.updateUserBalance(balance.toNumber()); - } + onMount(async () => { + console.log("onmount wallet", $store); + if ( + window && + window.localStorage && + window.localStorage["wc@2:client:0.3//session"] && + window.localStorage["wc@2:client:0.3//session"] !== "[]" + ) { + const sessions = JSON.parse(window.localStorage["wc@2:client:0.3//session"]); + const lastSession = sessions[sessions.length - 1].topic; + store.updateSdk(SDK.WC2); + await connectWalletWithExistingSession(lastSession); + } else { + await connectWallet(); } }); afterUpdate(async () => { - if ($store.wallet) { + if ($store.wallet instanceof BeaconWallet) { const activeAccount = await $store.wallet.client.getActiveAccount(); if (activeAccount) { const peers = await $store.wallet.client.getPeers(); @@ -115,6 +217,8 @@ connectedWallet = peers[0].name; } } + } else if ($store.wallet instanceof WalletConnect2) { + connectedWallet = $store.wallet.getPeerMetadata().name; } }); @@ -225,9 +329,11 @@
Connected to: {$store.networkType}
-
- Matrix node: {$store.matrixNode} -
+ {#if $store.wallet instanceof BeaconWallet} +
+ Matrix node: {$store.matrixNode} +
+ {/if}
Wallet: {connectedWallet}
@@ -238,10 +344,24 @@   Disconnect +
+ {#if $store.availableAccounts} +
+
Switch account
+ {#each $store.availableAccounts as pkh} + + {/each} + {/if} +
{/if} {:else} +