Skip to content

Commit

Permalink
Merge pull request #29 from Libertai/reza/test-provider
Browse files Browse the repository at this point in the history
Solana support
  • Loading branch information
aliel authored Oct 27, 2024
2 parents 670c033 + aed7ea2 commit 5dec9e2
Show file tree
Hide file tree
Showing 13 changed files with 855 additions and 68 deletions.
659 changes: 654 additions & 5 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@aleph-sdk/base": "^1.1.0",
"@aleph-sdk/client": "^1.1.0",
"@aleph-sdk/message": "^1.1.0",
"@aleph-sdk/solana": "^1.2.1",
"@libertai/libertai-js": "0.0.10",
"@quasar/extras": "^1.16.12",
"@tanstack/vue-query": "^5.51.21",
Expand All @@ -49,6 +50,7 @@
"pinia": "^2.2.1",
"pinia-plugin-persistedstate": "^3.2.1",
"quasar": "^2.16.8",
"solana-wallets-vue": "^0.6.1",
"stream": "^0.0.3",
"uuid": "^10.0.0",
"viem": "^2.19.1",
Expand Down
30 changes: 30 additions & 0 deletions public/icons.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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: ['utils', 'wagmi', 'solana'],

// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
css: ['app.scss', 'tailwind.css'],
Expand Down
12 changes: 12 additions & 0 deletions src/boot/solana.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { boot } from 'quasar/wrappers';
import SolanaWallets from 'solana-wallets-vue';
import 'solana-wallets-vue/styles.css';

const walletOptions = {
wallets: [],
autoConnect: true,
};

export default boot(({ app }) => {
app.use(SolanaWallets, walletOptions);
});
96 changes: 84 additions & 12 deletions src/components/AccountButton.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,49 @@
<template>
<div style="display: inline-block">
<q-btn-dropdown v-if="!account.isConnected.value" color="primary" label="Connect wallet" no-caps rounded unelevated>
<wallet-modal-provider :dark="!!$q.dark.mode" container="body">
<template #default="modalScope">
<slot v-bind="modalScope">
<q-btn ref="openSolanaModal" class="tw-hidden" @click="modalScope.openModal" />
</slot>
</template>
</wallet-modal-provider>

<q-btn-dropdown
v-if="accountStore.account === null"
auto-close
color="primary"
label="Connect wallet"
no-caps
rounded
unelevated
>
<q-btn
v-for="connector in config.connectors"
:key="connector.uid"
class="row tw-mx-auto"
no-caps
rounded
unelevated
@click="connect({ connector })"
@click="wagmiConnect({ connector })"
>
<ltai-icon :name="getConnectorIconName(connector.id)" class="tw-mr-1" />
<span>{{ connector.name }}</span>
</q-btn>
<q-btn
key="solana"
class="row tw-mx-auto"
no-caps
rounded
unelevated
@click="($refs.openSolanaModal as HTMLButtonElement).click()"
>
<ltai-icon :name="getConnectorIconName('solana')" class="tw-mr-1" />
<span>Solana</span>
</q-btn>
</q-btn-dropdown>
<q-btn-dropdown
v-else
:label="`${account.address.value?.slice(0, 4)}...${account.address.value?.slice(-2)}`"
:label="`${accountStore.account.address?.slice(0, 4)}...${accountStore.account.address?.slice(-2)}`"
class="border-primary-highlight gt-sm"
icon="img:icons/avatar.svg"
no-caps
Expand All @@ -26,7 +53,7 @@
>
<div class="row no-wrap q-pa-md q-pt-none">
<div class="column items-center">
<div class="text-small tw-mb-1">{{ account.address.value }}</div>
<div class="text-small tw-mb-1">{{ accountStore.account.address }}</div>

<q-btn
v-close-popup
Expand All @@ -50,33 +77,58 @@ import { useAccountStore } from 'stores/account';
import { useAccount, useConnect, useDisconnect } from '@wagmi/vue';
import { watchAccount } from '@wagmi/vue/actions';
import { config } from 'src/config/wagmi';
import { watchEffect } from 'vue';
import { watch, watchEffect } from 'vue';
import LtaiIcon from 'components/libertai/LtaiIcon.vue';
import { useWallet, WalletModalProvider } from 'solana-wallets-vue';
const accountStore = useAccountStore();
const account = useAccount();
const { connect } = useConnect();
const { disconnect } = useDisconnect();
// wagmi
const wagmiAccount = useAccount();
const { connect: wagmiConnect } = useConnect();
const { disconnect: wagmiDisconnect } = useDisconnect();
// solana
const { publicKey: solanaPubKey, disconnect: solanaDisconnect } = useWallet();
if (account.isConnected.value) {
accountStore.onAccountChange();
// wagmi account already connected
if (wagmiAccount.isConnected.value) {
accountStore.onAccountChange({ address: wagmiAccount.address.value!, chain: 'base' });
}
// solana account already connected
if (solanaPubKey.value !== null) {
accountStore.onAccountChange({ address: solanaPubKey.value.toBase58(), chain: 'solana' });
}
// watching wagmi account changes
watchEffect((onCleanup) => {
const unwatch = watchAccount(config, {
async onChange(newAccount) {
if (newAccount.address === undefined) {
accountStore.onDisconnect();
if (accountStore.account?.chain !== 'solana') {
accountStore.onDisconnect();
}
return;
}
await accountStore.onAccountChange();
await accountStore.onAccountChange({ address: newAccount.address, chain: 'base' });
},
});
onCleanup(unwatch);
});
// watching solana account changes
watch(
() => solanaPubKey.value,
(newValue) => {
if (newValue === null) {
accountStore.onDisconnect();
} else if (newValue.toBase58() !== accountStore.account?.address) {
accountStore.onAccountChange({ address: newValue.toBase58(), chain: 'solana' });
}
},
);
const getConnectorIconName = (connectorId: string): string => {
switch (connectorId) {
case 'io.rabby':
Expand All @@ -85,8 +137,28 @@ const getConnectorIconName = (connectorId: string): string => {
return 'svguse:icons.svg#metamask';
case 'walletConnect':
return 'svguse:icons.svg#walletConnect';
case 'solana':
return 'svguse:icons.svg#solana';
default:
return 'svguse:icons.svg#wallet';
}
};
const disconnect = () => {
const account = accountStore.account;
if (account === null) {
return;
}
switch (account.chain) {
case 'base':
wagmiDisconnect();
break;
case 'solana':
solanaDisconnect();
break;
}
accountStore.onDisconnect();
};
</script>
10 changes: 3 additions & 7 deletions src/layouts/MainLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<div class="row q-gutter-x-sm">
<q-btn
v-if="!account.isConnected.value"
v-if="accountStore.account === null"
:class="$q.screen.gt.sm ? '' : 'float-right q-pa-sm'"
no-caps
rounded
Expand All @@ -30,14 +30,14 @@
:text-color="$q.screen.gt.sm ? 'white' : 'black'"
:to="{
name: 'tokens-detail',
params: { address: account.address.value },
params: { address: accountStore!.account.address },
}"
no-caps
rounded
unelevated
>
<ltai-icon v-if="!$q.screen.gt.sm" left name="svguse:icons.svg#tokens-star" />
<span :key="account.address.value"
<span :key="accountStore!.account.address"
>{{ accountStore.ltaiBalance.toFixed(0) }} <span v-if="$q.screen.gt.sm">$LTAI</span></span
>
</q-btn>
Expand Down Expand Up @@ -101,19 +101,15 @@
import { ref } from 'vue';
import AccountButton from 'src/components/AccountButton.vue';
import UserSettingsDialog from 'components/dialog/UserSettingsDialog.vue';
import { useAccount } from '@wagmi/vue';
import { useAccountStore } from 'stores/account';
import ChatsList from 'components/ChatsList.vue';
import LtaiIcon from 'components/libertai/LtaiIcon.vue';
const leftDrawerOpen = ref(false);
const showUserSettingsDialog = ref(false);
// Setup Stores
const accountStore = useAccountStore();
const account = useAccount();
function toggleLeftDrawer() {
leftDrawerOpen.value = !leftDrawerOpen.value;
}
Expand Down
4 changes: 1 addition & 3 deletions src/pages/KnowledgeBase.vue
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ import { useRoute, useRouter } from 'vue-router';
import { KnowledgeBase, KnowledgeBaseIdentifier, KnowledgeDocument } from 'src/types/knowledge';
import { useKnowledgeStore } from 'stores/knowledge';
import { exportFile, useQuasar } from 'quasar';
import { useAccount } from '@wagmi/vue';
import { useAccountStore } from 'stores/account';
import { filesize } from 'filesize';
import LtaiIcon from 'components/libertai/LtaiIcon.vue';
Expand All @@ -187,7 +186,6 @@ import EmptyState from 'components/EmptyState.vue';
const $q = useQuasar();
const route = useRoute();
const router = useRouter();
const account = useAccount();
const accountStore = useAccountStore();
const knowledgeStore = useKnowledgeStore();
Expand All @@ -210,7 +208,7 @@ watch(
);
async function loadKnowledgeBase(id: string) {
if (!account.isConnected.value) {
if (accountStore.account === null) {
$q.notify({ message: 'Account not connected', color: 'negative' });
await router.push({ path: '/' });
return;
Expand Down
7 changes: 4 additions & 3 deletions src/pages/KnowledgeBasesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,23 @@ import KnowledgeBaseCreationDialog from 'components/dialog/KnowledgeBaseCreation
import { useKnowledgeStore } from 'stores/knowledge';
import LtaiIcon from 'components/libertai/LtaiIcon.vue';
import dayjs from 'dayjs';
import { useAccount } from '@wagmi/vue';
import { useQuasar } from 'quasar';
import { useRouter } from 'vue-router';
import EmptyState from 'components/EmptyState.vue';
import { useAccountStore } from 'stores/account';
const $q = useQuasar();
const router = useRouter();
const account = useAccount();
const accountStore = useAccountStore();
const knowledgeStore = useKnowledgeStore();
const createKnowledgeDialog = ref(false);
const isLoading = ref(false);
onMounted(async () => {
if (!account.isConnected.value) {
if (accountStore.account === null) {
$q.notify({ message: 'Account not connected', color: 'negative' });
await router.push({ path: '/' });
return;
Expand Down
14 changes: 1 addition & 13 deletions src/pages/TokensDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,14 @@
import { onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useTokensStore } from 'stores/tokens';
import { useAccount } from '@wagmi/vue';
import web3 from 'web3';
import { useQuasar } from 'quasar';
const route = useRoute();
const router = useRouter();
const tokensStore = useTokensStore();
const account = useAccount();
const $q = useQuasar();
// got address as an address part from vue router
Expand Down Expand Up @@ -104,15 +103,4 @@ watch(
immediate: true,
},
);
watch(
() => account.address.value as string,
async (newAddress: string, oldAddress: string) => {
if (oldAddress === address.value) {
await router.push({
name: 'tokens-detail',
params: { address: newAddress },
});
}
},
);
</script>
Loading

0 comments on commit 5dec9e2

Please sign in to comment.