web3 & dsa

This commit is contained in:
Georges KABBOUCHI 2021-07-19 22:35:31 +03:00
parent 7370cb306f
commit 7f60036a6f
10 changed files with 3198 additions and 62 deletions

1
assets/coinbase.svg Normal file
View File

@ -0,0 +1 @@
<svg viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="c"><stop stop-color="#2E66F8" offset="0%"/><stop stop-color="#124ADB" offset="100%"/></linearGradient><circle id="a" cx="59.928" cy="59.928" r="59.928"/></defs><g fill="none" fill-rule="evenodd"><path fill="#FFF" fill-rule="nonzero" d="M0 0h128v128H0z"/><path fill="#FFF" fill-rule="nonzero" d="M0 0h128v128H0z"/><path d="M0 0h128v128H0z"/><path d="M19 64c0 24.853 20.147 45 45 45s45-20.147 45-45-20.147-45-45-45-45 20.147-45 45zm33.5-14.5a3 3 0 00-3 3v23a3 3 0 003 3h23a3 3 0 003-3v-23a3 3 0 00-3-3h-23z" fill="#FFF"/><g transform="translate(4 4)"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><g mask="url(#b)"><path d="M0 0h119.856v119.856H0z"/><rect fill="url(#c)" fill-rule="nonzero" width="119.856" height="119.856" rx="48"/><path d="M24.97 59.928c0 19.307 15.651 34.958 34.958 34.958s34.958-15.651 34.958-34.958S79.235 24.97 59.928 24.97 24.97 40.62 24.97 59.928zm26.024-11.264a2.33 2.33 0 00-2.33 2.33v17.868a2.33 2.33 0 002.33 2.33h17.868a2.33 2.33 0 002.33-2.33V50.994a2.33 2.33 0 00-2.33-2.33H50.994z" fill="#FFF"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,5 +1,6 @@
<svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M16.6589 22.4944V22.9705C16.6553 23.0305 16.6432 23.2967 16.4393 23.4989C16.2438 23.6802 16.0193 23.6658 15.9722 23.6632H15.971C15.889 23.6528 15.6259 23.6032 15.4739 23.3736C15.3856 23.2201 15.3388 23.043 15.3387 22.8622C15.3368 22.8196 15.3376 22.7769 15.3411 22.7344C15.3465 22.6857 15.3449 22.6364 15.3363 22.5883C15.3093 22.4455 15.2448 22.3141 15.1504 22.21C15.025 22.0735 14.8575 21.9918 14.6798 21.9804C14.3878 21.97 14.103 22.1943 13.9775 22.5387V23.7624C13.9574 23.9362 13.8803 24.0964 13.7604 24.2142C13.6404 24.3319 13.4854 24.3993 13.3234 24.4042C13.1669 24.4066 13.0144 24.3506 12.8917 24.2455C12.769 24.1405 12.6837 23.9928 12.65 23.8276V22.5309C12.6189 22.3657 12.5372 22.2166 12.4181 22.1077C12.299 21.9988 12.1495 21.9365 11.9936 21.9308C11.831 21.9279 11.6728 21.987 11.5465 22.0977C11.4203 22.2084 11.3342 22.3636 11.3033 22.5361V24.9234C11.2701 25.0874 11.1859 25.2342 11.0646 25.3391C10.9434 25.4441 10.7925 25.5009 10.6372 25.5C10.4921 25.4957 10.3522 25.4416 10.2376 25.3454C10.123 25.2492 10.0397 25.116 10 24.9651V12.3817C10.0434 11.8547 10.2558 9.92399 11.7474 8.33769C13.5237 6.44613 15.7611 6.48787 16.1521 6.50353C18.3556 6.58441 19.7699 7.95677 20.1392 8.33769C21.7128 9.96834 21.9517 11.9617 22 12.4835L21.9916 18.706L21.9831 24.9286C21.9499 25.0819 21.8723 25.2197 21.7616 25.322C21.6509 25.4243 21.5129 25.4857 21.3677 25.4974C21.0274 25.513 20.7064 25.2156 20.6702 24.8034V22.5152C20.637 22.346 20.55 22.1946 20.4244 22.0874C20.2987 21.9801 20.1423 21.9238 19.9823 21.9282C19.813 21.9371 19.6529 22.014 19.5332 22.1438C19.4136 22.2736 19.3431 22.447 19.3355 22.63V23.6919C19.3303 23.8648 19.2689 24.0302 19.1621 24.1591C19.0552 24.2879 18.9098 24.3719 18.7514 24.3964C18.5849 24.4173 18.417 24.3715 18.2795 24.2677C18.1421 24.1638 18.0447 24.0091 18.0056 23.8328V22.6353C17.9963 22.4674 17.935 22.3077 17.8318 22.1819C17.7285 22.056 17.5891 21.9713 17.436 21.9413C17.2663 21.9145 17.0934 21.956 16.9501 22.058C16.8069 22.16 16.7032 22.3152 16.6589 22.4944ZM14.8825 12.5617C14.8825 12.7437 14.8494 12.9238 14.785 13.0919C14.7206 13.26 14.6262 13.4127 14.5072 13.5414C14.3882 13.67 14.2469 13.7721 14.0914 13.8417C13.9359 13.9113 13.7693 13.9471 13.601 13.9471C13.4327 13.9471 13.266 13.9113 13.1105 13.8417C12.955 13.7721 12.8138 13.67 12.6948 13.5414C12.5757 13.4127 12.4813 13.26 12.4169 13.0919C12.3525 12.9238 12.3194 12.7437 12.3194 12.5617C12.3194 12.1943 12.4544 11.8419 12.6948 11.5821C12.9351 11.3223 13.2611 11.1763 13.601 11.1763C13.9409 11.1763 14.2668 11.3223 14.5072 11.5821C14.7475 11.8419 14.8825 12.1943 14.8825 12.5617ZM18.0346 13.9471C18.3745 13.9471 18.7005 13.8012 18.9408 13.5414C19.1811 13.2815 19.3162 12.9292 19.3162 12.5617C19.3162 12.1943 19.1811 11.8419 18.9408 11.5821C18.7005 11.3223 18.3745 11.1763 18.0346 11.1763C17.6947 11.1763 17.3687 11.3223 17.1284 11.5821C16.888 11.8419 16.753 12.1943 16.753 12.5617C16.753 12.9292 16.888 13.2815 17.1284 13.5414C17.3687 13.8012 17.6947 13.9471 18.0346 13.9471ZM17.0064 15.0716C17.0064 15.0716 16.8785 15.6795 16.2631 15.7578C15.1915 15.8961 15.066 15.0716 15.066 15.0716C15.066 15.0716 15.0032 14.6229 15.4714 14.7716C15.9397 14.9203 16.613 14.7716 16.613 14.7716C16.613 14.7716 17.103 14.6438 17.0064 15.0716Z"
fill="currentColor" />
fill="currentColor
" />
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,137 @@
<template>
<div class="relative w-[162px]" v-click-outside="hide" v-if="activeAccount">
<button
type="button"
class="bg-white relative w-full border border-gray-300 rounded-md shadow-sm pl-3 pr-10 py-2 text-left focus:outline-none focus:ring-1 focus:ring-[#0846E4] focus:border-[#0846E4] sm:text-sm"
aria-haspopup="listbox"
aria-expanded="true"
aria-labelledby="listbox-label"
@click="show = !show"
>
<span
class="flex items-center capitalize text-primary-blue-dark text-sm font-medium"
>
<span class="text-primary-gray text-xs mr-2.5">
Account
</span>
#{{ activeAccount.id }}
</span>
<span
class="absolute inset-y-0 right-0 flex items-center pr-4 pointer-events-none"
>
<svg
:class="{ 'rotate-180': show }"
width="11"
height="7"
viewBox="0 0 11 7"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5.5 5.75L6.20711 6.45711C5.81658 6.84763 5.18342 6.84763 4.79289 6.45711L5.5 5.75ZM1.29289 2.95711L0.585786 2.25L2 0.835786L2.70711 1.54289L1.29289 2.95711ZM8.29289 1.54289L9 0.835786L10.4142 2.25L9.70711 2.95711L8.29289 1.54289ZM4.79289 6.45711L1.29289 2.95711L2.70711 1.54289L6.20711 5.04289L4.79289 6.45711ZM4.79289 5.04289L8.29289 1.54289L9.70711 2.95711L6.20711 6.45711L4.79289 5.04289Z"
:fill="show ? '#0846E4' : '#161E2E'"
/>
</svg>
</span>
</button>
<!--
Select popover, show/hide based on select state.
Entering: ""
From: ""
To: ""
Leaving: "transition ease-in duration-100"
From: "opacity-100"
To: "opacity-0"
-->
<div v-show="show" class="w-full px-2 absolute z-10 mt-0.5">
<ul
class="w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm divide-y divide-[#556D9C]/8"
tabindex="-1"
role="listbox"
aria-labelledby="listbox-label"
aria-activedescendant="listbox-option-3"
>
<!--
Select option, manage highlight styles based on mouseenter/mouseleave and keyboard navigation.
Highlighted: "text-white bg-indigo-600", Not Highlighted: "text-gray-900"
-->
<li
v-for="account in accounts"
:key="account.id"
@click="setAccount(account)"
class="cursor-pointer select-none relative py-3 pl-3 pr-9 hover:bg-primary-blue-dark/[0.07]"
id="listbox-option-0"
role="option"
>
<!-- Selected: "font-semibold", Not Selected: "font-normal" -->
<span class="flex items-center text-primary-blue-dark">
#{{ account.id }}
</span>
<span
v-if="activeAccount.id === account.id"
class="text-primary-blue-dark absolute inset-y-0 right-0 flex items-center pr-4"
>
<svg
width="8"
height="10"
viewBox="0 0 8 10"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0.5 5.86603C-0.166667 5.48113 -0.166667 4.51888 0.5 4.13397L6.5 0.669874C7.16667 0.284973 8 0.766099 8 1.5359L8 8.4641C8 9.2339 7.16667 9.71503 6.5 9.33013L0.5 5.86603Z"
fill="#3F75FF"
/>
</svg>
</span>
</li>
<li
@click="createAccount"
class="cursor-pointer select-none relative py-3 px-3 hover:bg-primary-blue-dark/[0.07]"
id="listbox-option-0"
role="option"
>
<!-- Selected: "font-semibold", Not Selected: "font-normal" -->
<span class="flex items-center text-xs justify-center">
<span class="text-primary-blue-dark mr-1">+</span> Create New
</span>
</li>
</ul>
</div>
</div>
</template>
<script>
import { defineComponent, ref, watch } from '@nuxtjs/composition-api'
import { useDSA } from "~/composables/useDSA";
export default defineComponent({
setup() {
const { accounts, activeAccount, createAccount, creatingAccount, setAccount } = useDSA()
const show = ref(false)
const hide = () => {
show.value = false
}
watch(activeAccount, hide);
return {
hide,
show,
accounts,
activeAccount,
createAccount,
creatingAccount,
setAccount,
}
},
})
</script>

View File

@ -20,18 +20,41 @@
</div>
<div class="flex items-center space-x-2.5">
<button class="bg-primary-blue-dark hover:bg-primary-blue-hover shadow text-white p-3 rounded-[6px] h-9 flex items-center justify-center w-40">
<button
v-if="!active"
@click="activate"
class="bg-primary-blue-dark hover:bg-primary-blue-hover shadow text-white p-3 rounded-[6px] h-9 flex items-center justify-center w-40"
>
Connect
</button>
<button
v-else
@click="deactivate"
class="bg-primary-blue-dark hover:bg-primary-blue-hover shadow text-white p-3 rounded-[6px] h-9 flex items-center justify-center w-40"
>
Disonnect
</button>
<AccountSwitcher v-if="active" />
<NetworkSwitcher />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api";
import { useWeb3 } from "~/composables/useWeb3";
export default defineComponent({
setup() {}
setup() {
const { active, activate, deactivate } = useWeb3();
return {
active,
activate,
deactivate
};
}
});
</script>

View File

@ -2,7 +2,7 @@
<div class="relative w-[148px]" v-click-outside="hide">
<button
type="button"
class="bg-white relative w-full border border-gray-300 rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default focus:outline-none focus:ring-1 focus:ring-[#0846E4] focus:border-[#0846E4] sm:text-sm"
class="bg-white relative w-full border border-gray-300 rounded-md shadow-sm pl-3 pr-10 py-2 text-left focus:outline-none focus:ring-1 focus:ring-[#0846E4] focus:border-[#0846E4] sm:text-sm"
aria-haspopup="listbox"
aria-expanded="true"
aria-labelledby="listbox-label"
@ -14,7 +14,7 @@
{{ activeNetwork.name }}
</span>
<span
class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none"
class="absolute inset-y-0 right-0 flex items-center pr-4 pointer-events-none"
>
<svg
:class="{ 'rotate-180': show }"

64
composables/useDSA.ts Normal file
View File

@ -0,0 +1,64 @@
import { computed, readonly, ref, watch } from "@nuxtjs/composition-api";
import { useWeb3 } from "./useWeb3";
//@ts-ignore
import DSA from "dsa-connect";
const dsa = ref<DSA>();
const accounts = ref<any[]>([]);
const activeAccount = ref<any>();
export function useDSA() {
const { web3, chainId } = useWeb3();
watch(
web3,
() => {
if (web3.value) {
dsa.value = new DSA(web3.value, chainId.value);
}
},
{ immediate: true }
);
watch(
dsa,
async () => {
if (dsa.value) {
accounts.value = await dsa.value.getAccounts();
if (accounts.value.length > 0) {
activeAccount.value = accounts.value[0];
}
}
},
{ immediate: true }
);
const creatingAccount = ref(false);
async function createAccount() {
creatingAccount.value = true;
try {
const transactionHash = await dsa.value.build({ version: 2 });
accounts.value = await dsa.value.getAccounts();
return transactionHash;
} catch (error) {
} finally {
creatingAccount.value = false;
}
}
function setAccount(account: any) {
activeAccount.value = account;
}
return {
dsa,
activeAccount: readonly(activeAccount),
accounts,
createAccount,
creatingAccount,
setAccount,
};
}

81
composables/useWeb3.ts Normal file
View File

@ -0,0 +1,81 @@
import { onMounted, ref } from "@nuxtjs/composition-api";
import Web3 from "web3";
import Web3Modal from "web3modal";
import WalletConnectProvider from "@walletconnect/web3-provider";
let web3Modal: Web3Modal;
let web3Provider: any;
const providerOptions = {
walletconnect: {
package: WalletConnectProvider,
options: {
infuraId: "4a22c748450749e49ca8124355fff52d"
}
}
};
const active = ref(false);
const chainId = ref<number>();
const account = ref<string>();
const web3 = ref<Web3>();
export function useWeb3() {
onMounted(async () => {
if (web3Modal) {
return;
}
web3Modal = new Web3Modal({
disableInjectedProvider: false,
cacheProvider: true,
providerOptions
});
if (web3Modal.cachedProvider) {
await activate();
}
});
const activate = async () => {
web3Provider = await web3Modal.connect();
active.value = true;
if (web3Provider.selectedAddress) {
account.value = web3Provider.selectedAddress;
} else if (web3Provider.accounts && web3Provider.accounts.length) {
account.value = web3Provider.accounts[0];
}
let newWeb3 = new Web3(web3Provider);
chainId.value = await newWeb3.eth.getChainId();
web3.value = newWeb3;
};
const deactivate = async () => {
if (
web3.value &&
web3.value.currentProvider &&
typeof web3.value.currentProvider === "object"
) {
//@ts-ignore
if (typeof web3.value.currentProvider.disconnect === "function") {
//@ts-ignore
web3.value.currentProvider.disconnect();
console.log("e");
}
}
web3Modal.clearCachedProvider();
web3Provider = undefined;
active.value = false;
web3.value = undefined;
account.value = undefined;
chainId.value = undefined;
};
return {
chainId,
web3,
active,
activate,
deactivate
};
}

View File

@ -42,12 +42,22 @@ import { defineComponent } from "@nuxtjs/composition-api";
import MakerDAOIcon from '~/assets/icons/makerdao.svg?inline'
import CompoundIcon from '~/assets/icons/compound.svg?inline'
import AaveIcon from '~/assets/icons/aave.svg?inline'
import { useWeb3 } from '~/composables/useWeb3'
export default defineComponent({
components: {
MakerDAOIcon,
CompoundIcon,
AaveIcon,
},
setup() {
const { active, activate, deactivate } = useWeb3();
return {
active,
activate,
deactivate,
}
}
})

View File

@ -11,9 +11,15 @@
"dependencies": {
"@nuxtjs/composition-api": "^0.24.7",
"@tailwindcss/forms": "^0.3.3",
"@vueuse/core": "^5.1.4",
"@walletconnect/web3-provider": "^1.4.1",
"core-js": "^3.15.1",
"dsa-connect": "^0.4.2",
"nuxt": "^2.15.7",
"v-click-outside": "^3.1.2"
"v-click-outside": "^3.1.2",
"walletlink": "^2.1.6",
"web3": "^1.4.0",
"web3modal": "^1.9.3"
},
"devDependencies": {
"@nuxt/types": "^2.15.7",

2925
yarn.lock

File diff suppressed because it is too large Load Diff