Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Wallet-Based Authentication with Stellar Wallet Kit #20

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,8 @@
"uuid": "^9.0.0",
"vite": "^4.5.5"
},
"type": "module"
"type": "module",
"dependencies": {
"@creit.tech/stellar-wallets-kit": "^1.2.1"
josephchimebuka marked this conversation as resolved.
Show resolved Hide resolved
}
}
41 changes: 39 additions & 2 deletions src/lib/stores/walletStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,48 @@ import { TransactionBuilder } from 'stellar-sdk'

function createWalletStore() {
/** @type {import('svelte/store').Writable<WalletStore>} */
const { subscribe, set } = persisted('bpa:walletStore', { keyId: '', publicKey: '' })

const { subscribe, set, } = persisted('bpa:walletStore', { keyId: '', publicKey: '' })
return {
subscribe,

/**
* Checks if a wallet is already registered
* @param {string} publicKey Public Stellar address
* @returns {Promise<boolean>} True if the wallet is registered, false otherwise
*/
josephchimebuka marked this conversation as resolved.
Show resolved Hide resolved



/**
* Registers a user by their public key (wallet-based registration)
* @param {Object} opts Options object
* @param {string} opts.publicKey Public Stellar address
*/
registerWithWallet: async ({ publicKey }) => {
try {
set({
keyId: publicKey, // Using publicKey as keyId for simplicity
publicKey: publicKey,
})
} catch (err) {
console.error('Error registering wallet', err)
// throw new Error(err.toString())
}
},

/**
* Logs in a user by their public key (wallet-based login)
* @param {string} publicKey Public Stellar address
*/
loginWithWallet: async (publicKey) => {
const storeValue = get(walletStore);
if (storeValue.publicKey !== publicKey) {
throw error(400, { message: 'Wallet not registered' });
}
// If the publicKey matches, the user is considered logged in.
// You might want to add additional logic here if needed.
},

/**
* Registers a user by storing their encrypted keypair in the browser's localStorage.
* @param {Object} opts Options object
Expand Down
2 changes: 1 addition & 1 deletion src/routes/dashboard/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import Navbar from './components/Navbar.svelte'
import Drawer from './components/Drawer.svelte'
import Footer from './components/Footer.svelte'
</script>
</script>

<div class="flex min-h-screen flex-col">
<Navbar />
Expand Down
42 changes: 42 additions & 0 deletions src/routes/dashboard/components/WalletKitProvider.svelte
josephchimebuka marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!-- src/lib/components/WalletComponent.svelte -->
<script>
import { goto } from '$app/navigation';
import { walletStore } from '$lib/stores/walletStore';
// @ts-ignore
import { StellarWalletsKit, WalletNetwork, allowAllModules, XBULL_ID } from '@creit.tech/stellar-wallets-kit'



export let buttonText = 'Connect Wallet';
const kit = new StellarWalletsKit({
network: WalletNetwork.TESTNET,
selectedWalletId: XBULL_ID,
modules: allowAllModules(),
});

const connectWallet = async () => {
try {
await kit.openModal({
// @ts-ignore
onWalletSelected: async (option) => {
kit.setWallet(option.id);
const { address } = await kit.getAddress();

if (address) {
await walletStore.registerWithWallet({ publicKey: address });
goto('/dashboard');
}
}
});
} catch (error) {
console.error('Error connecting wallet:', error);
}
};

export { connectWallet };
</script>

<!-- You can provide a button or any UI elements if needed -->
<button type="button" class="btn-secondary btn" on:click={connectWallet}>
{buttonText}
</button>
13 changes: 12 additions & 1 deletion src/routes/login/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ for submission to the network.
import { goto } from '$app/navigation'
import { errorMessage } from '$lib/stores/alertsStore'
import { walletStore } from '$lib/stores/walletStore'

import WalletKitProvider from '../dashboard/components/WalletKitProvider.svelte'
josephchimebuka marked this conversation as resolved.
Show resolved Hide resolved
// Define some component variables that will be used throughout the page
let pincode = ''







/**
* Our `login` function ensures the the user has entered a valid pincode for the encrypted keypair, and then redirects them to the dashboard page.
* @async
Expand Down Expand Up @@ -86,6 +92,11 @@ for submission to the network.
<div class="form-control mt-6">
<button class="btn-primary btn">Login</button>
</div>


<div class="form-control mt-2">
<WalletKitProvider buttonText='Login with wallet'/>
</div>
</form>
</div>
</div>
Expand Down
12 changes: 11 additions & 1 deletion src/routes/signup/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ circumstance.
import { goto } from '$app/navigation'
import { walletStore } from '$lib/stores/walletStore'
import { fundWithFriendbot } from '$lib/stellar/horizonQueries'

import WalletKitProvider from '../dashboard/components/WalletKitProvider.svelte';
// The `open` Svelte context is used to open the confirmation modal
import { getContext } from 'svelte'
const { open } = getContext('simple-modal')
Expand All @@ -40,6 +40,8 @@ circumstance.
let showSecret = false
let pincode = ''



/**
* Takes an action after the pincode has been confirmed by the user.
* @async
Expand Down Expand Up @@ -74,6 +76,11 @@ circumstance.
onConfirm: onConfirm,
})
}





</script>

<div class="hero min-h-screen bg-base-200">
Expand Down Expand Up @@ -147,6 +154,9 @@ circumstance.
<div class="form-control mt-6">
<button type="submit" class="btn-primary btn">Signup</button>
</div>
<div class="form-control mt-2">
<WalletKitProvider buttonText='Sign up with wallet'/>
</div>
<div class="form-control my-1">
<div class="label">
<a class="link-hover label-text-alt link" href="/login">
Expand Down
Loading