Skip to content

Commit

Permalink
feat(subscriptions): Basic frontend working with Hold subscriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
RezaRahemtola committed Sep 29, 2024
1 parent 7958888 commit 30c038c
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 25 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Use the testnet in development
# ALEPH_API_URL=https://api.twentysix.testnet.network

# APIs
LTAI_SUBSCRIPTIONS_API_URL=http://localhost:8000
2 changes: 1 addition & 1 deletion quasar.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = configure(function (ctx) {
// app boot file (/src/boot)
// --> boot files are part of "main.js"
// https://v2.quasar.dev/quasar-cli-vite/boot-files
boot: ['utils', 'wagmi'],
boot: ['axios', 'utils', 'wagmi'],

// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
css: ['app.scss', 'tailwind.css'],
Expand Down
18 changes: 9 additions & 9 deletions src/apis/subscriptions/services.gen.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
// This file is auto-generated by @hey-api/openapi-ts

import { createClient, createConfig, type Options } from '@hey-api/client-axios';
import type { SubscribeHoldSubscriptionPostData, SubscribeHoldSubscriptionPostError, SubscribeHoldSubscriptionPostResponse, UnsubscribeHoldSubscriptionDeleteData, UnsubscribeHoldSubscriptionDeleteError, UnsubscribeHoldSubscriptionDeleteResponse, RefreshActiveHoldSubscriptionsHoldRefreshPostError, RefreshActiveHoldSubscriptionsHoldRefreshPostResponse, HoldSubscriptionMessagesHoldMessageGetData, HoldSubscriptionMessagesHoldMessageGetError, HoldSubscriptionMessagesHoldMessageGetResponse, RefreshSubsRefreshPostError, RefreshSubsRefreshPostResponse, GetUserSubscriptionsSubscriptionsGetData, GetUserSubscriptionsSubscriptionsGetError, GetUserSubscriptionsSubscriptionsGetResponse } from './types.gen';
import type { GetUserSubscriptionsSubscriptionsGetData, GetUserSubscriptionsSubscriptionsGetError, GetUserSubscriptionsSubscriptionsGetResponse, SubscribeHoldSubscriptionPostData, SubscribeHoldSubscriptionPostError, SubscribeHoldSubscriptionPostResponse, UnsubscribeHoldSubscriptionDeleteData, UnsubscribeHoldSubscriptionDeleteError, UnsubscribeHoldSubscriptionDeleteResponse, RefreshActiveHoldSubscriptionsHoldRefreshPostError, RefreshActiveHoldSubscriptionsHoldRefreshPostResponse, HoldSubscriptionMessagesHoldMessageGetData, HoldSubscriptionMessagesHoldMessageGetError, HoldSubscriptionMessagesHoldMessageGetResponse, RefreshSubsRefreshPostError, RefreshSubsRefreshPostResponse } from './types.gen';

export const client = createClient(createConfig());

/**
* Get User Subscriptions
*/
export const getUserSubscriptionsSubscriptionsGet = <ThrowOnError extends boolean = false>(options: Options<GetUserSubscriptionsSubscriptionsGetData, ThrowOnError>) => { return (options?.client ?? client).get<GetUserSubscriptionsSubscriptionsGetResponse, GetUserSubscriptionsSubscriptionsGetError, ThrowOnError>({
...options,
url: '/subscriptions'
}); };

/**
* Subscribe
*/
Expand Down Expand Up @@ -45,12 +53,4 @@ export const holdSubscriptionMessagesHoldMessageGet = <ThrowOnError extends bool
export const refreshSubsRefreshPost = <ThrowOnError extends boolean = false>(options?: Options<unknown, ThrowOnError>) => { return (options?.client ?? client).post<RefreshSubsRefreshPostResponse, RefreshSubsRefreshPostError, ThrowOnError>({
...options,
url: '/subs/refresh'
}); };

/**
* Get User Subscriptions
*/
export const getUserSubscriptionsSubscriptionsGet = <ThrowOnError extends boolean = false>(options: Options<GetUserSubscriptionsSubscriptionsGetData, ThrowOnError>) => { return (options?.client ?? client).get<GetUserSubscriptionsSubscriptionsGetResponse, GetUserSubscriptionsSubscriptionsGetError, ThrowOnError>({
...options,
url: '/subscriptions'
}); };
22 changes: 11 additions & 11 deletions src/apis/subscriptions/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ export type ValidationError = {
type: string;
};

export type GetUserSubscriptionsSubscriptionsGetData = {
query: {
address: string;
};
};

export type GetUserSubscriptionsSubscriptionsGetResponse = (GetUserSubscriptionsResponse);

export type GetUserSubscriptionsSubscriptionsGetError = (HTTPValidationError);

export type SubscribeHoldSubscriptionPostData = {
body: HoldPostSubscriptionBody;
};
Expand Down Expand Up @@ -111,14 +121,4 @@ export type HoldSubscriptionMessagesHoldMessageGetError = (HTTPValidationError);

export type RefreshSubsRefreshPostResponse = (SubsPostRefreshSubscriptionsResponse);

export type RefreshSubsRefreshPostError = unknown;

export type GetUserSubscriptionsSubscriptionsGetData = {
query: {
address: string;
};
};

export type GetUserSubscriptionsSubscriptionsGetResponse = (GetUserSubscriptionsResponse);

export type GetUserSubscriptionsSubscriptionsGetError = (HTTPValidationError);
export type RefreshSubsRefreshPostError = unknown;
8 changes: 8 additions & 0 deletions src/boot/axios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { boot } from 'quasar/wrappers';
import { client } from 'src/apis/subscriptions/services.gen';

export default boot(() => {
client.setConfig({
baseURL: process.env.LTAI_SUBSCRIPTIONS_API_URL,
});
});
42 changes: 42 additions & 0 deletions src/pages/Subscriptions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<template>
<section class="max-sm:tw-mx-4 sm:tw-mx-10 tw-my-5">
<q-linear-progress v-if="!subscriptionsStore.isLoaded" indeterminate />
<p v-else-if="subscriptionsStore.subscriptions.length === 0">No subscriptions</p>
<div v-for="subscription of subscriptionsStore.subscriptions" v-else :key="subscription.id">
<p>{{ subscription.type }} {{ subscription.provider }}</p>
</div>

<q-btn
class="border-primary-highlight"
no-caps
rounded
text-color="dark-mode-text"
unelevated
@click="subscriptionsStore.holdSubscribe('standard')"
>
New standard hold subscription
</q-btn>
</section>
</template>

<script lang="ts" setup>
import { onMounted } from 'vue';
import { useAccount } from '@wagmi/vue';
import { useRouter } from 'vue-router';
import { useQuasar } from 'quasar';
import { useSubscriptionStore } from 'stores/subscription';
const $q = useQuasar();
const router = useRouter();
const account = useAccount();
const subscriptionsStore = useSubscriptionStore();
onMounted(async () => {
if (!account.isConnected.value) {
$q.notify({ message: 'Account not connected', color: 'negative' });
await router.push({ path: '/' });
return;
}
});
</script>
4 changes: 4 additions & 0 deletions src/router/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ const routes = [
path: 'persona-management',
component: () => import('pages/PersonaManagement.vue'),
},
{
path: 'subscriptions',
component: () => import('pages/Subscriptions.vue'),
},
],
},

Expand Down
6 changes: 4 additions & 2 deletions src/stores/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { config } from 'src/config/wagmi';
import { base } from '@wagmi/vue/chains';
import { useTokensStore } from 'stores/tokens';
import { useKnowledgeStore } from 'stores/knowledge';
import { useSubscriptionStore } from 'stores/subscription';

const LTAI_BASE_ADDRESS = '0xF8B1b47AA748F5C7b5D0e80C726a843913EB573a';

Expand All @@ -23,12 +24,13 @@ export const useAccountStore = defineStore('account', {
async onAccountChange() {
const tokensStore = useTokensStore();
const knowledgeStore = useKnowledgeStore();
const subscriptionsStore = useSubscriptionStore();

this.ltaiBalance = await this.getLTAIBalance();

await this.initAlephStorage();
await tokensStore.update();
await knowledgeStore.load();

await Promise.all([tokensStore.update(), knowledgeStore.load(), subscriptionsStore.load()]);
},

async initAlephStorage() {
Expand Down
2 changes: 1 addition & 1 deletion src/stores/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const useSettingsStore = defineStore('settings', {
},

async persistOnAleph(settings: SettingsPersistedOnAleph) {
const account: any = useAccountStore();
const account = useAccountStore();

if (account.alephStorage !== null) {
await account.alephStorage.saveSettings(settings);
Expand Down
68 changes: 68 additions & 0 deletions src/stores/subscription.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { defineStore } from 'pinia';
import {
BaseSubscription,
getUserSubscriptionsSubscriptionsGet,
holdSubscriptionMessagesHoldMessageGet,
subscribeHoldSubscriptionPost,
SubscriptionType,
} from 'src/apis/subscriptions';
import { getAccount, signMessage } from '@wagmi/core';
import { config } from 'src/config/wagmi';

type SubscriptionState = {
subscriptions: BaseSubscription[];
isLoaded: boolean;
};

export const useSubscriptionStore = defineStore('subscriptions', {
state: (): SubscriptionState => ({
subscriptions: [],
isLoaded: false,
}),
actions: {
async load() {
const account = getAccount(config);
const address = account.address;

if (address === undefined) {
return;
}

const response = await getUserSubscriptionsSubscriptionsGet({ query: { address } });

this.subscriptions = response.data?.subscriptions ?? [];
this.isLoaded = true;
},

async holdSubscribe(subscriptionType: SubscriptionType) {
const account = getAccount(config);
const address = account.address;

if (address === undefined) {
return;
}

const messagesResponse = await holdSubscriptionMessagesHoldMessageGet({
query: { subscription_type: subscriptionType },
});

if (messagesResponse.data === undefined) {
throw new Error(
messagesResponse.error.detail?.toString() ?? 'Unable to fetch the message to sign to subscribe',
);
}

const messageToSign = messagesResponse.data.subscribe_message;
const hash = await signMessage(config, { message: messageToSign });

const subscriptionResponse = await subscribeHoldSubscriptionPost({

Check warning on line 58 in src/stores/subscription.ts

View workflow job for this annotation

GitHub Actions / build

'subscriptionResponse' is assigned a value but never used. Allowed unused vars must match /^_/u
body: {
signature: hash,
type: 'standard',
account: { chain: 'base', address },
},
});
// TODO: handle errors and success
},
},
});
2 changes: 1 addition & 1 deletion src/utils/aleph-persistent-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class AlephPersistentStorage {
private encryptionPrivateKey: PrivateKey,
) {}

static async signBaseMessage() {
static signBaseMessage() {
return signMessage(config, { message: MESSAGE });
}

Expand Down

0 comments on commit 30c038c

Please sign in to comment.