Skip to content

Commit

Permalink
feat: integrate wallet connect
Browse files Browse the repository at this point in the history
Co-authored-by: Konstantinos Paparas <[email protected]>
  • Loading branch information
lukicenturi and kelsos committed Nov 22, 2024
1 parent b555759 commit ebb08a3
Show file tree
Hide file tree
Showing 16 changed files with 1,896 additions and 675 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ NUXT_PUBLIC_MAINTENANCE=false
NUXT_PUBLIC_TESTING=true
#PROXY_DOMAIN=rotki.com
#PROXY_INSECURE=true #When set it will proxy to http instead of https
NUXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=
1 change: 1 addition & 0 deletions components/account/home/AccountAddress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { required } from '@vuelidate/validators';
import { get, objectOmit, set } from '@vueuse/core';
import { storeToRefs } from 'pinia';
import { useMainStore } from '~/store';
import { toMessages } from '~/utils/validation';
const store = useMainStore();
const state = reactive({
Expand Down
1 change: 1 addition & 0 deletions components/account/home/AccountInformation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { required } from '@vuelidate/validators';
import { get, objectOmit, set } from '@vueuse/core';
import { storeToRefs } from 'pinia';
import { useMainStore } from '~/store';
import { toMessages } from '~/utils/validation';
const store = useMainStore();
const state = reactive({
Expand Down
1 change: 1 addition & 0 deletions components/account/home/ChangePassword.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useVuelidate } from '@vuelidate/core';
import { minLength, required, sameAs } from '@vuelidate/validators';
import { get, set } from '@vueuse/core';
import { useMainStore } from '~/store';
import { toMessages } from '~/utils/validation';
import type { ActionResult } from '~/types/common';
const loading = ref(false);
Expand Down
109 changes: 44 additions & 65 deletions components/checkout/pay/CryptoPage.vue
Original file line number Diff line number Diff line change
@@ -1,75 +1,26 @@
<script lang="ts" setup>
import detectEthereumProvider from '@metamask/detect-provider';
import { useAppKit, useAppKitAccount } from '@reown/appkit/vue';
import { get, set } from '@vueuse/core';
import { useMainStore } from '~/store';
import { PaymentError } from '~/types/codes';
import { PaymentMethod } from '~/types/payment';
import { assert } from '~/utils/assert';
import { useLogger } from '~/utils/use-logger';
import type { CryptoPayment, PaymentStep, Provider } from '~/types';
import type { CryptoPayment, PaymentStep } from '~/types';
const { t } = useI18n();
const loading = ref(false);
const data = ref<CryptoPayment | null>(null);
const metamaskSupport = ref(false);
const { cryptoPayment, switchCryptoPlan, deletePendingPayment, subscriptions } = useMainStore();
const { plan } = usePlanParams();
const { currency } = useCurrencyParams();
const { subscriptionId } = useSubscriptionIdParam();
const route = useRoute();
let provider: Provider | null = null;
const config = useRuntimeConfig();
const {
payWithMetamask,
state: currentState,
error,
clearErrors,
} = useWeb3Payment(
data,
() => {
assert(provider);
return provider;
},
!!config.public.testing,
);
const logger = useLogger();
onMounted(async () => {
const selectedPlan = get(plan);
const selectedCurrency = get(currency);
if (selectedPlan && selectedCurrency) {
provider = await detectEthereumProvider();
logger.debug(
`provider: ${!!provider}, is metamask: ${provider?.isMetaMask}`,
);
set(metamaskSupport, !!provider);
set(loading, true);
const subId = get(subscriptionId);
const result = await cryptoPayment(selectedPlan, selectedCurrency, subId);
if (result.isError) {
if (result.code === PaymentError.UNVERIFIED)
set(error, t('subscription.error.unverified_email'));
else
set(error, result.error.message);
}
else if (result.result.transactionStarted) {
await navigateTo('/home/subscription');
}
else {
set(data, result.result);
}
set(loading, false);
}
else {
await navigateTo('/products');
}
});
const { pay, state: currentState, error, clearErrors } = useWeb3Payment(data);
const account = useAppKitAccount();
const { open } = useAppKit();
const step = computed<PaymentStep>(() => {
const errorMessage = get(error);
Expand Down Expand Up @@ -126,6 +77,19 @@ function back() {
});
}
async function changePaymentMethod() {
set(loading, true);
const response = await deletePendingPayment();
if (!response.isError) {
back();
}
else {
set(error, response.error.message);
set(loading, false);
}
}
watch(plan, async (plan) => {
const selectedCurrency = get(currency);
assert(selectedCurrency);
Expand All @@ -143,18 +107,32 @@ watch(plan, async (plan) => {
set(loading, false);
});
async function changePaymentMethod() {
set(loading, true);
const response = await deletePendingPayment();
onMounted(async () => {
const selectedPlan = get(plan);
const selectedCurrency = get(currency);
if (selectedPlan && selectedCurrency) {
set(loading, true);
const subId = get(subscriptionId);
const result = await cryptoPayment(selectedPlan, selectedCurrency, subId);
if (result.isError) {
if (result.code === PaymentError.UNVERIFIED)
set(error, t('subscription.error.unverified_email'));
else
set(error, result.error.message);
}
else if (result.result.transactionStarted) {
await navigateTo('/home/subscription');
}
else {
set(data, result.result);
}
if (!response.isError) {
back();
set(loading, false);
}
else {
set(error, response.error.message);
set(loading, false);
await navigateTo('/products');
}
}
});
</script>

<template>
Expand Down Expand Up @@ -182,9 +160,10 @@ async function changePaymentMethod() {
:pending="pending || currentState === 'pending'"
v-bind="{ success, failure, status }"
:loading="loading"
:metamask-support="metamaskSupport"
:plan="plan"
@pay="payWithMetamask()"
:connected="account.isConnected"
@pay="pay()"
@connect="open()"
@change="changePaymentMethod()"
@clear:errors="clearErrors()"
/>
Expand Down
50 changes: 37 additions & 13 deletions components/checkout/pay/CryptoPaymentForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ const props = defineProps<{
success: boolean;
failure: boolean;
loading: boolean;
metamaskSupport: boolean;
connected: boolean;
status: PaymentStep;
}>();
const emit = defineEmits<{
(e: 'change'): void;
(e: 'pay'): void;
(e: 'connect'): void;
(e: 'clear:errors'): void;
}>();
Expand Down Expand Up @@ -96,7 +97,8 @@ const stopWatcher = watchEffect(() => {
const { copy: copyToClipboard } = useClipboard({ source: qrText });
const isBtc = computed(() => get(data).chainName === 'bitcoin');
const payWithMetamask = () => emit('pay');
const pay = () => emit('pay');
const connect = () => emit('connect');
const changePaymentMethod = () => emit('change');
const clearErrors = () => emit('clear:errors');
const css = useCssModule();
Expand Down Expand Up @@ -173,14 +175,14 @@ const showChangePaymentDialog = ref(false);
warning
/>
<div :class="css.hint">
{{ t('home.plans.tiers.step_3.metamask.notice') }}
{{ t('home.plans.tiers.step_3.wallet.notice') }}

<div :class="css.info">
<p>
{{ t('home.plans.tiers.step_3.metamask.paid_notice_1') }}
{{ t('home.plans.tiers.step_3.wallet.paid_notice_1') }}
</p>
<p>
{{ t('home.plans.tiers.step_3.metamask.paid_notice_2') }}
{{ t('home.plans.tiers.step_3.wallet.paid_notice_2') }}
</p>
</div>
</div>
Expand All @@ -197,21 +199,43 @@ const showChangePaymentDialog = ref(false);
</div>
<div
v-if="!isBtc"
class="grow"
class="grow flex gap-1"
>
<RuiButton
:disabled="!metamaskSupport || processing"
:loading="processing"
v-if="!connected"
color="primary"
:loading="processing"
:disabled="processing"
size="lg"
class="w-full"
@click="payWithMetamask()"
@click="connect()"
>
<template #prepend>
<MetamaskIcon class="h-6 w-6 mr-2" />
</template>
{{ t('home.plans.tiers.step_3.metamask.action') }}
{{ t('home.plans.tiers.step_3.wallet.connect_wallet') }}
</RuiButton>
<template v-else>
<RuiButton
:loading="processing"
:disabled="processing"
color="primary"
size="lg"
class="w-full"
@click="pay()"
>
{{ t('home.plans.tiers.step_3.wallet.pay_with_wallet') }}
</RuiButton>

<RuiButton
size="lg"
color="secondary"
class="!px-3"
@click="connect()"
>
<RuiIcon
name="link"
size="20"
/>
</RuiButton>
</template>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit ebb08a3

Please sign in to comment.