steem-auth-vue
Version:
A Vue 3 authentication component for Steem blockchain and MeeRay sidechain
406 lines (314 loc) • 11.3 kB
Markdown
# Steem Auth Vue Component
This project provides a Vue 3 authentication and transaction component library for the Steem blockchain, supporting multi-account management, secure PIN-based encryption, and a user-friendly UI/UX.
## Project Structure
- `src/index.ts` — main entry point for the component
- `src/components` — Vue component definitions (including `SteemAuth.vue`, `SteemTransactions.vue`, `PinModal.vue`)
- `src/services` — services for interacting with the Steem blockchain
- `src/utils` — utility functions
- `src/types` — TypeScript type definitions
- `dist/` — built component files (after running `npm run build`)
- `test/` — test application for testing the component
## Features
- **Multi-account support** with add, remove, and switch logic
- **PIN-based encryption** for secure posting key storage (see `PinModal.vue`)
- **Keychain and SteemLogin integration**
- **Schema-driven forms** for Steem operations
- **Defensive UI/UX** with error handling and feedback
## Development
- Vue 3 with TypeScript
- Vite for development and building
- Steem-related libraries: `dsteem`, `steem`, `steemlogin`
## Building the Component
Run:
```sh
npm run build
```
This will create the following files in the `dist` directory:
- `steem-auth-vue.es.js` — ES module version
- `steem-auth-vue.umd.js` — UMD version for browsers
- `style.css` — Component styles
- Type definition files
## Usage Example
Import the component and styles in your app:
```js
import { SteemAuth } from '../dist/steem-auth-vue.es.js';
import '../dist/style.css';
import { useAuthStore } from '../dist/steem-auth-vue.es.js';
```
Register and use the component in your template:
```vue
<template>
<SteemAuth :appName="'MyApp'" :callbackURL="'http://localhost:3000/callback'" />
<SteemTransactions />
</template>
<script setup>
import { SteemAuth } from '../dist/steem-auth-vue.es.js';
import { SteemTransactions } from '../dist/steem-auth-vue.es.js';
</script>
```
### PIN Modal
- The `PinModal` component is used for secure PIN entry and confirmation during login and transaction flows.
- PIN entry is required for encrypting/decrypting the posting key for Steem direct login accounts.
### Defensive Template Example
If you use dynamic forms or async data, always guard against undefined objects:
```vue
<form v-if="inputValues[operation.type]">
<!-- form fields -->
</form>
```
## TypeScript Strictness & Best Practices
- **Unused variables in templates or functions will cause build errors.**
- For unused variables in `v-for`, use `_` instead of a named variable (e.g., `(_, idx) in items`).
- For unused function parameters, prefix with `_` (e.g., `function handler(_e) { ... }`).
- If you encounter build errors related to unused variables, check your component templates and scripts for unused `v-for` variables or function parameters and fix them as shown in `PinModal.vue`.
## Troubleshooting
### Build Errors: Unused Variables
**Error Example:**
```
error TS6133: 'digit' is declared but its value is never read.
```
**Solution:**
- Replace unused variables in `v-for` with `_`.
- Prefix unused function parameters with `_`.
- Remove unused imports.
### Runtime Errors: Cannot read properties of undefined/null
If you see errors like `Cannot read properties of undefined (reading 'from')` or similar, ensure you are guarding against undefined objects in your templates (e.g., use `v-if` to check objects exist before accessing their properties). For dynamic or async data, always check that required objects/arrays are initialized before rendering components or forms.
### Modal/Component Errors
If you use modals or dynamic components, always ensure required props are present and valid when the component is rendered. Use defensive `v-if` checks as needed.
---
For more details, see the code comments and the `PinModal.vue` example for best practices.
## Installation
```bash
npm install steem-auth-vue
```
## Usage
### Basic Usage
```vue
<template>
<div>
<SteemAuth />
</div>
</template>
<script setup>
import { SteemAuth } from 'steem-auth-vue';
import 'steem-auth-vue/dist/style.css'; // Import styles
</script>
```
### Customizing Authentication Methods
You can customize which authentication methods are available by passing props to the SteemAuth component:
```vue
<template>
<div>
<!-- Only enable SteemLogin (disable Keychain and direct login) -->
<SteemAuth
:enableSteemLogin="true"
:enableKeychain="false"
:enableDirectLogin="false"
/>
<!-- Only enable Keychain authentication -->
<SteemAuth
:enableSteemLogin="false"
:enableKeychain="true"
:enableDirectLogin="false"
/>
<!-- Only enable direct login with posting key -->
<SteemAuth
:enableSteemLogin="false"
:enableKeychain="false"
:enableDirectLogin="true"
/>
</div>
</template>
<script setup>
import { SteemAuth } from 'steem-auth-vue';
import 'steem-auth-vue/dist/style.css'; // Import styles
</script>
```
### Dark Theme Support
The component supports both light and dark themes. Users can toggle between themes using the built-in theme toggle button. You can also set the default theme:
```vue
<template>
<div>
<!-- Start with dark theme by default -->
<SteemAuth :defaultDarkMode="true" @theme-change="handleThemeChange" />
</div>
</template>
<script setup>
import { SteemAuth } from 'steem-auth-vue';
import 'steem-auth-vue/dist/style.css'; // Import styles
const handleThemeChange = (isDark) => {
console.log('Theme changed:', isDark ? 'dark' : 'light');
// You can apply additional theme changes to your app based on this event
};
</script>
```
### Using the Auth Store
Access the authentication state in your components:
```vue
<template>
<div>
<p v-if="authStore.state.isAuthenticated">
Logged in as: {{ authStore.state.username }}
</p>
<p v-else>
Not logged in
</p>
</div>
</template>
<script setup>
import { useAuthStore } from 'steem-auth-vue';
const authStore = useAuthStore();
</script>
```
### Transaction Components
Use the transaction components to send operations to the Steem blockchain or Meeray sidechain:
```vue
<template>
<div>
<SteemAuth />
<!-- For Steem blockchain transactions -->
<SteemTransactions v-if="authStore.state.isAuthenticated" />
<!-- For Meeray sidechain transactions -->
<MeerayTransactions v-if="authStore.state.isAuthenticated" />
</div>
</template>
<script setup>
import { SteemAuth, SteemTransactions, MeerayTransactions, useAuthStore } from 'steem-auth-vue';
import 'steem-auth-vue/dist/style.css'; // Import styles
const authStore = useAuthStore();
</script>
```
## Meeray Sidechain Support
This component supports [Meeray](https://github.com/FutureShockco/meeray), a next generation sidechain for the Steem blockchain that provides advanced features like tokens, NFTs, markets, and staking.
### Using Transactions Service Directly
If you need more flexibility than the provided components, you can use the TransactionService directly:
#### Sending Steem Blockchain Transactions
```vue
<template>
<div>
<button @click="sendTransfer" :disabled="!authStore.state.isAuthenticated">
Send 0.001 STEEM to recipient
</button>
<div v-if="result">Transaction ID: {{ result }}</div>
<div v-if="error" class="error">{{ error }}</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useAuthStore, TransactionService } from 'steem-auth-vue';
const authStore = useAuthStore();
const result = ref('');
const error = ref('');
async function sendTransfer() {
try {
// Clear previous results
result.value = '';
error.value = '';
// Set up transaction data
const tx = {
from: authStore.state.username,
to: 'recipient-username',
amount: '0.001 STEEM',
memo: 'Payment for services'
};
// Send the transaction
const response = await TransactionService.send('transfer', tx, {
requiredAuth: 'active' // 'active' or 'posting' depending on operation type
});
// Handle the response
result.value = response.id || response.result?.id;
} catch (err) {
error.value = err instanceof Error ? err.message : 'Failed to send transaction';
}
}
</script>
```
#### Sending Meeray Sidechain Transactions
```vue
<template>
<div>
<button @click="approveNode" :disabled="!authStore.state.isAuthenticated">
Approve Node
</button>
<div v-if="result">Transaction ID: {{ result }}</div>
<div v-if="error" class="error">{{ error }}</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useAuthStore, TransactionService } from 'steem-auth-vue';
const authStore = useAuthStore();
const result = ref('');
const error = ref('');
async function approveNode() {
try {
// Clear previous results
result.value = '';
error.value = '';
// Create the custom_json payload for an Meeray operation
const payload = {
required_auths: [authStore.state.username],
required_posting_auths: [],
id: 'sidechain',
json: JSON.stringify({
contract: 'approve_node',
payload: {
target: 'node-account-name'
}
})
};
// Send the transaction
const response = await TransactionService.send('custom_json', payload, {
requiredAuth: 'active'
});
// Handle the response
result.value = response.id || response.result?.id;
} catch (err) {
error.value = err instanceof Error ? err.message : 'Failed to send transaction';
}
}
</script>
```
## Documentation
For detailed documentation on all available operations:
- [Steem Transactions](./docs/steem-transactions.md) - Complete guide for Steem blockchain operations
- [Meeray Transactions](./docs/meeray-transactions.md) - Complete guide for Meeray sidechain operations
## License
MIT
## Features
- Steem Keychain integration
- SteemLogin support
- Direct posting key authentication
- Persistent authentication state
- TypeScript support
- Pinia store integration
- Steem blockchain transactions
- Meeray sidechain transactions
## Authentication Methods
1. **Steem Keychain**
- Uses the Steem Keychain browser extension
- No need to enter posting keys
- Most secure method
2. **SteemLogin**
- OAuth-based authentication
- Token-based authentication
3. **Direct Posting Key**
- Manual posting key entry
- Basic authentication method
## Environment Variables
Create a `.env` file in your project root:
```env
VITE_APP_NAME=your-app-name
```
## Development
```bash
# Install dependencies
npm install
# Build the component
npm run build
# Test the component
cd test
npm run dev
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.