From 86945aa05757e212431f62ca45d1fd22c78049ca Mon Sep 17 00:00:00 2001 From: silverpill Date: Mon, 5 Sep 2022 15:57:09 +0000 Subject: [PATCH] Create payment page for Monero subscriptions --- src/api/search.ts | 17 +- src/api/subscriptions-common.ts | 24 ++ src/api/subscriptions-monero.ts | 40 +++ src/api/users.ts | 19 ++ src/components/SubscriptionEthereum.vue | 25 +- src/components/SubscriptionMonero.vue | 332 ++++++++++++++++++++++++ src/views/SubscriptionPage.vue | 9 + 7 files changed, 444 insertions(+), 22 deletions(-) create mode 100644 src/components/SubscriptionMonero.vue diff --git a/src/api/search.ts b/src/api/search.ts index 30f98c9..ead8870 100644 --- a/src/api/search.ts +++ b/src/api/search.ts @@ -27,7 +27,22 @@ export async function getSearchResults( return data } -export async function searchProfileByEthereumAddress( +export async function searchProfilesByAcct( + acct: string, +): Promise { + const url = `${BACKEND_URL}/api/v1/accounts/search` + const response = await http(url, { + method: "GET", + queryParams: { q: acct }, + }) + const data = await response.json() + if (response.status !== 200) { + throw new Error(data.message) + } + return data +} + +export async function searchProfilesByEthereumAddress( walletAddress: string, ): Promise { const url = `${BACKEND_URL}/api/v1/accounts/search_did` diff --git a/src/api/subscriptions-common.ts b/src/api/subscriptions-common.ts index d044cb5..bc7eb50 100644 --- a/src/api/subscriptions-common.ts +++ b/src/api/subscriptions-common.ts @@ -22,3 +22,27 @@ export async function getSubscriptionOptions( return data } } + +export interface SubscriptionDetails { + id: number, + expires_at: string, +} + +export async function getSubscription( + senderId: string, + recipientId: string, +): Promise { + const url = `${BACKEND_URL}/api/v1/subscriptions/find` + const response = await http(url, { + method: "GET", + queryParams: { sender_id: senderId, recipient_id: recipientId }, + }) + const data = await response.json() + if (response.status === 200) { + return data + } else if (response.status === 404) { + return null + } else { + throw new Error(data.message) + } +} diff --git a/src/api/subscriptions-monero.ts b/src/api/subscriptions-monero.ts index 09e9115..10438ea 100644 --- a/src/api/subscriptions-monero.ts +++ b/src/api/subscriptions-monero.ts @@ -37,3 +37,43 @@ export async function enableMoneroSubscriptions( return data } } + +export interface Invoice { + id: string, + sender_id: string, + recipient_id: string, + payment_address: string, + status: string, +} + +export async function createInvoice( + senderId: string, + recipientId: string, +): Promise { + const url = `${BACKEND_URL}/api/v1/subscriptions/invoices` + const response = await http(url, { + method: "POST", + json: { sender_id: senderId, recipient_id: recipientId }, + }) + const data = await response.json() + if (response.status !== 200) { + throw new Error(data.message) + } else { + return data + } +} + +export async function getInvoice( + invoiceId: string, +): Promise { + const url = `${BACKEND_URL}/api/v1/subscriptions/invoices/${invoiceId}` + const response = await http(url, { + method: "GET", + }) + const data = await response.json() + if (response.status !== 200) { + throw new Error(data.message) + } else { + return data + } +} diff --git a/src/api/users.ts b/src/api/users.ts index aa7f506..fedad8c 100644 --- a/src/api/users.ts +++ b/src/api/users.ts @@ -40,6 +40,25 @@ export interface Profile { statuses_count: number; } +export function guest() { + return { + id: "", + username: "", + acct: "", + url: "", + display_name: "You", + note: null, + avatar: null, + header: null, + identity_proofs: [], + payment_options: [], + fields: [], + followers_count: 0, + following_count: 0, + statuses_count: 0, + } +} + export interface User extends Profile { source: Source; } diff --git a/src/components/SubscriptionEthereum.vue b/src/components/SubscriptionEthereum.vue index 2018211..78c1ffd 100644 --- a/src/components/SubscriptionEthereum.vue +++ b/src/components/SubscriptionEthereum.vue @@ -109,8 +109,8 @@ import { BigNumber, FixedNumber } from "ethers" import { onMounted, watch } from "vue" import { $, $$, $computed, $ref } from "vue/macros" -import { searchProfileByEthereumAddress } from "@/api/search" -import { Profile, ProfileWrapper } from "@/api/users" +import { searchProfilesByEthereumAddress } from "@/api/search" +import { guest, Profile, ProfileWrapper } from "@/api/users" import { cancelSubscription, getSubscriptionConfig, @@ -132,29 +132,12 @@ const props = defineProps<{ profile: Profile, }>() -const guest: Profile = { - id: "", - username: "", - acct: "", - url: "", - display_name: "You", - note: null, - avatar: null, - header: null, - identity_proofs: [], - payment_options: [], - fields: [], - followers_count: 0, - following_count: 0, - statuses_count: 0, -} - const { currentUser } = $(useCurrentUser()) const { instance } = $(useInstanceInfo()) const { connectWallet: connectEthereumWallet } = useWallet() const recipient = new ProfileWrapper(props.profile) const recipientEthereumAddress = recipient.getVerifiedEthereumAddress() -let sender = $ref(new ProfileWrapper(currentUser || guest)) +let sender = $ref(new ProfileWrapper(currentUser || guest())) let { walletAddress, walletError, getSigner } = $(useWallet()) let subscriptionsEnabled = $ref(null) let subscriptionConfig = $ref(null) @@ -217,7 +200,7 @@ async function checkSubscription() { return } // Update sender info - const profiles = await searchProfileByEthereumAddress(walletAddress) + const profiles = await searchProfilesByEthereumAddress(walletAddress) if (profiles.length === 1) { sender = new ProfileWrapper(profiles[0]) } else { diff --git a/src/components/SubscriptionMonero.vue b/src/components/SubscriptionMonero.vue new file mode 100644 index 0000000..6bfdd9a --- /dev/null +++ b/src/components/SubscriptionMonero.vue @@ -0,0 +1,332 @@ + + + + + diff --git a/src/views/SubscriptionPage.vue b/src/views/SubscriptionPage.vue index 038e9cf..470be10 100644 --- a/src/views/SubscriptionPage.vue +++ b/src/views/SubscriptionPage.vue @@ -3,6 +3,7 @@ @@ -15,6 +16,7 @@ import { useRoute } from "vue-router" import { getProfile, Profile } from "@/api/users" import SidebarLayout from "@/components/SidebarLayout.vue" import SubscriptionEthereum from "@/components/SubscriptionEthereum.vue" +import SubscriptionMonero from "@/components/SubscriptionMonero.vue" import { useCurrentUser } from "@/store/user" import { useInstanceInfo } from "@/store/instance" @@ -46,4 +48,11 @@ function isEthereum(): boolean { } return blockchain.chain_id.startsWith("eip155") } + +function isMonero(): boolean { + if (!blockchain) { + return false + } + return blockchain.chain_id.startsWith("monero") +}