Show token balance on subscription page
This commit is contained in:
parent
9863e7866e
commit
3ef8190907
4 changed files with 93 additions and 18 deletions
|
@ -129,6 +129,15 @@ export async function getSubscriptionState(
|
||||||
return { senderBalance, recipientBalance }
|
return { senderBalance, recipientBalance }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getTokenBalance(
|
||||||
|
signer: Signer,
|
||||||
|
tokenAddress: string,
|
||||||
|
): Promise<BigNumber> {
|
||||||
|
const token = await getContract(Contracts.ERC20, tokenAddress, signer)
|
||||||
|
const balance = await token.balanceOf(signer.getAddress())
|
||||||
|
return balance
|
||||||
|
}
|
||||||
|
|
||||||
export async function makeSubscriptionPayment(
|
export async function makeSubscriptionPayment(
|
||||||
contractAddress: string,
|
contractAddress: string,
|
||||||
signer: Signer,
|
signer: Signer,
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="status">
|
<div class="status">
|
||||||
<template v-if="subscriptionState && !subscriptionState.senderBalance.isZero()">
|
<template v-if="subscriptionState && !subscriptionState.senderBalance.isZero()">
|
||||||
<div>Your balance {{ subscription.formatAmount(subscriptionState.senderBalance) }} {{ subscription.tokenSymbol }}</div>
|
<div>Your balance is {{ subscription.formatAmount(subscriptionState.senderBalance) }} {{ subscription.tokenSymbol }}</div>
|
||||||
<div>Subscription expires {{ subscription.getExpirationDate(subscriptionState.senderBalance).toLocaleString() }}</div>
|
<div>Subscription expires {{ subscription.getExpirationDate(subscriptionState.senderBalance).toLocaleString() }}</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>You are not subscribed yet</template>
|
<template v-else>You are not subscribed yet</template>
|
||||||
|
@ -45,17 +45,33 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<form class="payment" v-if="canSubscribe()">
|
<form class="payment" v-if="canSubscribe()">
|
||||||
<div class="input-group">
|
<div class="duration">
|
||||||
<label for="duration">Duration</label>
|
<label for="duration">Duration</label>
|
||||||
<input type="number" id="duration" v-model="paymentDuration" min="1">
|
<input type="number" id="duration" v-model="paymentDuration" min="1">
|
||||||
<span>months</span>
|
<span>months</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group">
|
<div>
|
||||||
<label>Amount</label>
|
<div class="payment-amount">
|
||||||
<span>{{ getPaymentAmount() }} {{ subscription.tokenSymbol }}</span>
|
<label>Amount</label>
|
||||||
|
<div>{{ getPaymentAmount() }} {{ subscription.tokenSymbol }}</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="tokenBalance !== null"
|
||||||
|
class="token-balance"
|
||||||
|
:class="{ error: !canPay() }"
|
||||||
|
@click="refreshTokenBalance()"
|
||||||
|
>
|
||||||
|
<label>You have</label>
|
||||||
|
<div>{{ subscription.formatAmount(tokenBalance) }} {{ subscription.tokenSymbol }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-row">
|
<div class="button-row">
|
||||||
<button type="submit" class="btn primary" @click.prevent="onMakeSubscriptionPayment()">
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn primary"
|
||||||
|
:disabled="!canPay()"
|
||||||
|
@click.prevent="onMakeSubscriptionPayment()"
|
||||||
|
>
|
||||||
<template v-if="!subscriptionState || subscriptionState.senderBalance.isZero()">Pay</template>
|
<template v-if="!subscriptionState || subscriptionState.senderBalance.isZero()">Pay</template>
|
||||||
<template v-else>Extend</template>
|
<template v-else>Extend</template>
|
||||||
</button>
|
</button>
|
||||||
|
@ -69,7 +85,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { FixedNumber } from "ethers"
|
import { BigNumber, FixedNumber } from "ethers"
|
||||||
import { onMounted, watch } from "vue"
|
import { onMounted, watch } from "vue"
|
||||||
import { $, $$, $ref } from "vue/macros"
|
import { $, $$, $ref } from "vue/macros"
|
||||||
|
|
||||||
|
@ -78,6 +94,7 @@ import {
|
||||||
cancelSubscription,
|
cancelSubscription,
|
||||||
getSubscriptionInfo,
|
getSubscriptionInfo,
|
||||||
getSubscriptionState,
|
getSubscriptionState,
|
||||||
|
getTokenBalance,
|
||||||
makeSubscriptionPayment,
|
makeSubscriptionPayment,
|
||||||
Subscription,
|
Subscription,
|
||||||
SubscriptionState,
|
SubscriptionState,
|
||||||
|
@ -122,6 +139,7 @@ let isLoading = $ref(false)
|
||||||
let subscriptionConfigured = $ref<boolean | null>(null)
|
let subscriptionConfigured = $ref<boolean | null>(null)
|
||||||
let subscription = $ref<Subscription | null>(null)
|
let subscription = $ref<Subscription | null>(null)
|
||||||
let subscriptionState = $ref<SubscriptionState | null>(null)
|
let subscriptionState = $ref<SubscriptionState | null>(null)
|
||||||
|
let tokenBalance = $ref<BigNumber | null>(null)
|
||||||
const paymentDuration = $ref<number>(1)
|
const paymentDuration = $ref<number>(1)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -165,7 +183,7 @@ async function checkSubscription() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (ethereumAddressMatch(walletAddress, recipientEthereumAddress)) {
|
if (ethereumAddressMatch(walletAddress, recipientEthereumAddress)) {
|
||||||
walletError = "incorrect wallet address"
|
walletError = "Incorrect wallet address"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
senderEthereumAddress = walletAddress.toLowerCase()
|
senderEthereumAddress = walletAddress.toLowerCase()
|
||||||
|
@ -180,6 +198,8 @@ async function checkSubscription() {
|
||||||
subscriptionConfigured = true
|
subscriptionConfigured = true
|
||||||
} else {
|
} else {
|
||||||
subscriptionConfigured = false
|
subscriptionConfigured = false
|
||||||
|
isLoading = false
|
||||||
|
return
|
||||||
}
|
}
|
||||||
subscriptionState = await getSubscriptionState(
|
subscriptionState = await getSubscriptionState(
|
||||||
instance.blockchain_contract_address,
|
instance.blockchain_contract_address,
|
||||||
|
@ -187,9 +207,14 @@ async function checkSubscription() {
|
||||||
walletAddress,
|
walletAddress,
|
||||||
recipientEthereumAddress,
|
recipientEthereumAddress,
|
||||||
)
|
)
|
||||||
|
tokenBalance = await getTokenBalance(signer, subscription.tokenAddress)
|
||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function canSubscribe(): boolean {
|
||||||
|
return subscriptionConfigured === true
|
||||||
|
}
|
||||||
|
|
||||||
function getPaymentAmount(): FixedNumber {
|
function getPaymentAmount(): FixedNumber {
|
||||||
if (!subscription) {
|
if (!subscription) {
|
||||||
return FixedNumber.from(0)
|
return FixedNumber.from(0)
|
||||||
|
@ -198,8 +223,20 @@ function getPaymentAmount(): FixedNumber {
|
||||||
return subscription.formatAmount(amount)
|
return subscription.formatAmount(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
function canSubscribe(): boolean {
|
function canPay(): boolean {
|
||||||
return subscriptionConfigured === true
|
if (!subscription || !tokenBalance) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const amount = subscription.pricePerMonthInt.mul(paymentDuration)
|
||||||
|
return amount.lte(tokenBalance)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refreshTokenBalance() {
|
||||||
|
if (!subscription) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const signer = getWeb3Provider().getSigner()
|
||||||
|
tokenBalance = await getTokenBalance(signer, subscription.tokenAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onMakeSubscriptionPayment() {
|
async function onMakeSubscriptionPayment() {
|
||||||
|
@ -234,6 +271,7 @@ async function onMakeSubscriptionPayment() {
|
||||||
walletAddress,
|
walletAddress,
|
||||||
recipientEthereumAddress,
|
recipientEthereumAddress,
|
||||||
)
|
)
|
||||||
|
tokenBalance = await getTokenBalance(signer, subscription.tokenAddress)
|
||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +286,8 @@ async function onCancelSubscription() {
|
||||||
if (
|
if (
|
||||||
!instance?.blockchain_contract_address ||
|
!instance?.blockchain_contract_address ||
|
||||||
!recipientEthereumAddress ||
|
!recipientEthereumAddress ||
|
||||||
!walletAddress
|
!walletAddress ||
|
||||||
|
!subscription
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -273,6 +312,7 @@ async function onCancelSubscription() {
|
||||||
walletAddress,
|
walletAddress,
|
||||||
recipientEthereumAddress,
|
recipientEthereumAddress,
|
||||||
)
|
)
|
||||||
|
tokenBalance = await getTokenBalance(signer, subscription.tokenAddress)
|
||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -332,6 +372,10 @@ async function onCancelSubscription() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wallet-error {
|
||||||
|
color: $error-color;
|
||||||
|
}
|
||||||
|
|
||||||
.loader {
|
.loader {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
@ -350,7 +394,7 @@ async function onCancelSubscription() {
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-subtext {
|
.price-subtext {
|
||||||
font-size: 14px;
|
font-size: $text-font-size;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
|
@ -364,12 +408,17 @@ async function onCancelSubscription() {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: $block-inner-padding;
|
gap: $block-inner-padding;
|
||||||
|
|
||||||
.input-group {
|
.duration,
|
||||||
|
.payment-amount,
|
||||||
|
.token-balance {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
font-size: 16px;
|
|
||||||
gap: $input-padding;
|
gap: $input-padding;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duration {
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -380,6 +429,23 @@ async function onCancelSubscription() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.payment-amount {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: $input-padding / 2;
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.token-balance {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
color: $error-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.button-row {
|
.button-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: $block-inner-padding;
|
gap: $block-inner-padding;
|
||||||
|
|
|
@ -110,7 +110,7 @@ async function checkSubscription() {
|
||||||
}
|
}
|
||||||
if (!ethereumAddressMatch(walletAddress, profileEthereumAddress)) {
|
if (!ethereumAddressMatch(walletAddress, profileEthereumAddress)) {
|
||||||
// Recipient must use verified account
|
// Recipient must use verified account
|
||||||
walletError = "incorrect wallet address"
|
walletError = "Incorrect wallet address"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const signer = getWeb3Provider().getSigner()
|
const signer = getWeb3Provider().getSigner()
|
||||||
|
|
|
@ -24,12 +24,12 @@ async function connectWallet(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
web3Provider = getWeb3Provider()
|
web3Provider = getWeb3Provider()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
walletError.value = "wallet not found"
|
walletError.value = "Wallet not found"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const signer = await getWallet(web3Provider)
|
const signer = await getWallet(web3Provider)
|
||||||
if (!signer) {
|
if (!signer) {
|
||||||
walletError.value = "wallet not connected"
|
walletError.value = "Wallet not connected"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
walletAddress.value = await signer.getAddress()
|
walletAddress.value = await signer.getAddress()
|
||||||
|
@ -47,7 +47,7 @@ async function connectWallet(): Promise<void> {
|
||||||
const instanceChainId = parseCAIP2_chainId(instance.value.blockchain_id)
|
const instanceChainId = parseCAIP2_chainId(instance.value.blockchain_id)
|
||||||
const walletChainId = await web3Provider.send("eth_chainId", [])
|
const walletChainId = await web3Provider.send("eth_chainId", [])
|
||||||
if (walletChainId !== instanceChainId) {
|
if (walletChainId !== instanceChainId) {
|
||||||
walletError.value = "incorrect network"
|
walletError.value = "Incorrect network"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue