@hydrawallet-sdk/core 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +707 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,707 @@
1
+ # @hydrawallet/core
2
+
3
+ A comprehensive Cardano wallet SDK designed specifically for **Browser DApps**. This core library provides essential wallet functionality with full support for modern build tools including **Vite** and **Rollup**, making it perfect for decentralized applications running in web browsers.
4
+
5
+ ## 🎯 Purpose
6
+
7
+ **@hydrawallet/core** is built specifically for browser-based decentralized applications (DApps) that need to interact with the Cardano blockchain. Whether you're building a DeFi protocol, NFT marketplace, or any Cardano-based web application, this SDK provides all the wallet functionality you need.
8
+
9
+ ## ✨ Key Features
10
+
11
+ - **🌐 Browser-First**: Optimized for web browsers and DApp integration
12
+ - **⚡ Modern Build Tools**: Full support for Vite, Rollup, and Webpack
13
+ - **🔐 Wallet Management**: Create, restore, and manage Cardano wallets
14
+ - **📱 DApp Integration**: Easy integration with browser-based applications
15
+ - **🔗 Network Support**: Mainnet, Testnet, and Preprod networks
16
+ - **💎 TypeScript**: Complete TypeScript support with type definitions
17
+ - **🚀 WASM Powered**: High-performance Cardano operations via WebAssembly
18
+ - **🏗️ HD Wallets**: Hierarchical Deterministic wallet implementation (BIP44)
19
+
20
+ ## 🛠️ Build Tool Support
21
+
22
+ ### Vite Integration
23
+
24
+ Perfect for modern Vite-based projects:
25
+
26
+ ```javascript
27
+ // vite.config.js
28
+ import { defineConfig } from 'vite'
29
+ import wasm from 'vite-plugin-wasm'
30
+ import topLevelAwait from 'vite-plugin-top-level-await'
31
+
32
+ export default defineConfig({
33
+ plugins: [
34
+ wasm(),
35
+ topLevelAwait()
36
+ ],
37
+ optimizeDeps: {
38
+ exclude: ['@emurgo/cardano-serialization-lib-browser']
39
+ }
40
+ })
41
+ ```
42
+
43
+ ### Rollup Integration
44
+
45
+ Seamless integration with Rollup:
46
+
47
+ ```javascript
48
+ // rollup.config.js
49
+ import wasm from '@rollup/plugin-wasm'
50
+
51
+ export default {
52
+ plugins: [
53
+ wasm({
54
+ maxFileSize: 0 // Remove file size limit for WASM
55
+ })
56
+ ],
57
+ external: ['@emurgo/cardano-serialization-lib-browser']
58
+ }
59
+ ```
60
+
61
+ ### Webpack Integration
62
+
63
+ Compatible with Webpack-based projects:
64
+
65
+ ```javascript
66
+ // webpack.config.js
67
+ module.exports = {
68
+ experiments: {
69
+ asyncWebAssembly: true,
70
+ topLevelAwait: true
71
+ },
72
+ externals: {
73
+ '@emurgo/cardano-serialization-lib-browser': 'CardanoWasm'
74
+ }
75
+ }
76
+ ```
77
+
78
+ ## 📦 Installation
79
+
80
+ ```bash
81
+ npm install @hydrawallet/core
82
+ # or
83
+ yarn add @hydrawallet/core
84
+ # or
85
+ pnpm add @hydrawallet/core
86
+ ```
87
+
88
+ ## 🚀 Quick Start for DApps
89
+
90
+ ### 1. Basic DApp Integration
91
+
92
+ ```typescript
93
+ import { AppWallet, NETWORK_ID } from '@hydrawallet/core'
94
+
95
+ // Initialize wallet for your DApp
96
+ class MyDApp {
97
+ private wallet: AppWallet | null = null
98
+
99
+ async connectWallet() {
100
+ // Create new wallet or restore existing
101
+ const mnemonic = AppWallet.brew()
102
+
103
+ this.wallet = new AppWallet({
104
+ networkId: NETWORK_ID.PREPROD, // Use MAINNET for production
105
+ key: {
106
+ type: 'mnemonic',
107
+ words: mnemonic
108
+ }
109
+ })
110
+
111
+ console.log('Wallet connected to DApp')
112
+ return this.wallet
113
+ }
114
+
115
+ async getWalletAddress() {
116
+ if (!this.wallet) throw new Error('Wallet not connected')
117
+
118
+ const account = this.wallet.getAccount(0, 0)
119
+ return account.address
120
+ }
121
+
122
+ async getWalletBalance() {
123
+ if (!this.wallet) throw new Error('Wallet not connected')
124
+
125
+ const address = await this.getWalletAddress()
126
+ return await this.wallet.getBalance(address)
127
+ }
128
+ }
129
+
130
+ // Usage in your DApp
131
+ const dapp = new MyDApp()
132
+ await dapp.connectWallet()
133
+ const address = await dapp.getWalletAddress()
134
+ const balance = await dapp.getWalletBalance()
135
+ ```
136
+
137
+ ### 2. React DApp Example
138
+
139
+ ```tsx
140
+ import React, { useState, useEffect } from 'react'
141
+ import { AppWallet, NETWORK_ID } from '@hydrawallet/core'
142
+
143
+ function WalletConnector() {
144
+ const [wallet, setWallet] = useState<AppWallet | null>(null)
145
+ const [address, setAddress] = useState<string>('')
146
+ const [balance, setBalance] = useState<string>('0')
147
+
148
+ const connectWallet = async () => {
149
+ try {
150
+ // In a real DApp, you might restore from localStorage or user input
151
+ const mnemonic = AppWallet.brew()
152
+
153
+ const newWallet = new AppWallet({
154
+ networkId: NETWORK_ID.PREPROD,
155
+ key: { type: 'mnemonic', words: mnemonic }
156
+ })
157
+
158
+ setWallet(newWallet)
159
+
160
+ const account = newWallet.getAccount(0, 0)
161
+ setAddress(account.address)
162
+
163
+ const walletBalance = await newWallet.getBalance(account.address)
164
+ setBalance(walletBalance)
165
+
166
+ } catch (error) {
167
+ console.error('Failed to connect wallet:', error)
168
+ }
169
+ }
170
+
171
+ return (
172
+ <div className="wallet-connector">
173
+ {!wallet ? (
174
+ <button onClick={connectWallet}>
175
+ Connect Wallet
176
+ </button>
177
+ ) : (
178
+ <div>
179
+ <p>Address: {address}</p>
180
+ <p>Balance: {balance} lovelace</p>
181
+ </div>
182
+ )}
183
+ </div>
184
+ )
185
+ }
186
+ ```
187
+
188
+ ### 3. Vue DApp Example
189
+
190
+ ```vue
191
+ <template>
192
+ <div class="wallet-connector">
193
+ <button v-if="!wallet" @click="connectWallet">
194
+ Connect Wallet
195
+ </button>
196
+ <div v-else>
197
+ <p>Address: {{ address }}</p>
198
+ <p>Balance: {{ balance }} lovelace</p>
199
+ </div>
200
+ </div>
201
+ </template>
202
+
203
+ <script setup lang="ts">
204
+ import { ref } from 'vue'
205
+ import { AppWallet, NETWORK_ID } from '@hydrawallet/core'
206
+
207
+ const wallet = ref<AppWallet | null>(null)
208
+ const address = ref('')
209
+ const balance = ref('0')
210
+
211
+ const connectWallet = async () => {
212
+ try {
213
+ const mnemonic = AppWallet.brew()
214
+
215
+ const newWallet = new AppWallet({
216
+ networkId: NETWORK_ID.PREPROD,
217
+ key: { type: 'mnemonic', words: mnemonic }
218
+ })
219
+
220
+ wallet.value = newWallet
221
+
222
+ const account = newWallet.getAccount(0, 0)
223
+ address.value = account.address
224
+
225
+ balance.value = await newWallet.getBalance(account.address)
226
+
227
+ } catch (error) {
228
+ console.error('Failed to connect wallet:', error)
229
+ }
230
+ }
231
+ </script>
232
+ ```
233
+
234
+ ## 🏗️ DApp Architecture
235
+
236
+ ### Recommended Architecture for Browser DApps
237
+
238
+ ```mermaid
239
+ graph TD
240
+ A[Browser DApp] --> B[Wallet Manager]
241
+ B --> C[@hydrawallet/core]
242
+ C --> D[Cardano WASM]
243
+ C --> E[Network Provider]
244
+
245
+ F[User Interface] --> B
246
+ G[Transaction Builder] --> C
247
+ H[State Management] --> B
248
+
249
+ E --> I[Blockfrost API]
250
+ E --> J[Custom RPC]
251
+
252
+ K[Local Storage] --> B
253
+ L[Session Storage] --> B
254
+ ```
255
+
256
+ ### Core Components for DApps
257
+
258
+ #### 1. **Wallet Manager**
259
+ ```typescript
260
+ export class WalletManager {
261
+ private wallet: AppWallet | null = null
262
+ private network: NETWORK_ID = NETWORK_ID.PREPROD
263
+
264
+ async initialize(mnemonic?: string) {
265
+ const words = mnemonic || this.loadFromStorage() || AppWallet.brew()
266
+
267
+ this.wallet = new AppWallet({
268
+ networkId: this.network,
269
+ key: { type: 'mnemonic', words }
270
+ })
271
+
272
+ this.saveToStorage(words)
273
+ return this.wallet
274
+ }
275
+
276
+ private saveToStorage(mnemonic: string) {
277
+ // Encrypt and save to localStorage
278
+ localStorage.setItem('wallet_mnemonic', this.encrypt(mnemonic))
279
+ }
280
+
281
+ private loadFromStorage(): string | null {
282
+ const encrypted = localStorage.getItem('wallet_mnemonic')
283
+ return encrypted ? this.decrypt(encrypted) : null
284
+ }
285
+ }
286
+ ```
287
+
288
+ #### 2. **Transaction Handler**
289
+ ```typescript
290
+ export class TransactionHandler {
291
+ constructor(private wallet: AppWallet) {}
292
+
293
+ async sendADA(toAddress: string, amount: string) {
294
+ const account = this.wallet.getAccount(0, 0)
295
+
296
+ const transaction = await this.wallet.buildTransaction({
297
+ outputs: [{
298
+ address: toAddress,
299
+ amount: amount
300
+ }],
301
+ changeAddress: account.address
302
+ })
303
+
304
+ const signedTx = await this.wallet.signTransaction(transaction)
305
+ return await this.wallet.submitTransaction(signedTx)
306
+ }
307
+
308
+ async sendNFT(toAddress: string, policyId: string, assetName: string) {
309
+ // NFT transfer logic
310
+ }
311
+ }
312
+ ```
313
+
314
+ ## 🌐 Network Configuration for DApps
315
+
316
+ ### Environment-based Network Selection
317
+
318
+ ```typescript
319
+ // config/networks.ts
320
+ export const getNetworkConfig = () => {
321
+ const env = process.env.NODE_ENV || 'development'
322
+
323
+ switch (env) {
324
+ case 'production':
325
+ return {
326
+ networkId: NETWORK_ID.MAINNET,
327
+ blockfrostUrl: 'https://cardano-mainnet.blockfrost.io/api/v0'
328
+ }
329
+ case 'staging':
330
+ return {
331
+ networkId: NETWORK_ID.PREPROD,
332
+ blockfrostUrl: 'https://cardano-preprod.blockfrost.io/api/v0'
333
+ }
334
+ default:
335
+ return {
336
+ networkId: NETWORK_ID.TESTNET,
337
+ blockfrostUrl: 'https://cardano-testnet.blockfrost.io/api/v0'
338
+ }
339
+ }
340
+ }
341
+
342
+ // Usage in DApp
343
+ const config = getNetworkConfig()
344
+ const wallet = new AppWallet({
345
+ networkId: config.networkId,
346
+ key: { type: 'mnemonic', words: mnemonic }
347
+ })
348
+ ```
349
+
350
+ ## 🔧 Advanced DApp Features
351
+
352
+ ### 1. Multi-Account Support
353
+
354
+ ```typescript
355
+ class MultiAccountWallet {
356
+ private wallet: AppWallet
357
+
358
+ constructor(wallet: AppWallet) {
359
+ this.wallet = wallet
360
+ }
361
+
362
+ getAccounts(count: number = 5) {
363
+ const accounts = []
364
+ for (let i = 0; i < count; i++) {
365
+ accounts.push(this.wallet.getAccount(0, i))
366
+ }
367
+ return accounts
368
+ }
369
+
370
+ async getAccountBalances() {
371
+ const accounts = this.getAccounts()
372
+ const balances = await Promise.all(
373
+ accounts.map(account =>
374
+ this.wallet.getBalance(account.address)
375
+ )
376
+ )
377
+
378
+ return accounts.map((account, index) => ({
379
+ ...account,
380
+ balance: balances[index]
381
+ }))
382
+ }
383
+ }
384
+ ```
385
+
386
+ ### 2. Transaction History
387
+
388
+ ```typescript
389
+ class TransactionHistory {
390
+ constructor(private wallet: AppWallet) {}
391
+
392
+ async getHistory(address: string, page: number = 1, limit: number = 10) {
393
+ const allTxs = await this.wallet.getTransactionHistory(address)
394
+
395
+ const start = (page - 1) * limit
396
+ const end = start + limit
397
+
398
+ return {
399
+ transactions: allTxs.slice(start, end),
400
+ total: allTxs.length,
401
+ page,
402
+ hasMore: end < allTxs.length
403
+ }
404
+ }
405
+
406
+ async getTransactionDetails(txHash: string) {
407
+ // Get detailed transaction information
408
+ return await this.wallet.getTransaction(txHash)
409
+ }
410
+ }
411
+ ```
412
+
413
+ ### 3. Asset Management
414
+
415
+ ```typescript
416
+ class AssetManager {
417
+ constructor(private wallet: AppWallet) {}
418
+
419
+ async getNativeAssets(address: string) {
420
+ const utxos = await this.wallet.getUtxos(address)
421
+ const assets = new Map()
422
+
423
+ utxos.forEach(utxo => {
424
+ if (utxo.assets) {
425
+ utxo.assets.forEach(asset => {
426
+ const key = `${asset.policyId}.${asset.assetName}`
427
+ const current = assets.get(key) || 0
428
+ assets.set(key, current + parseInt(asset.quantity))
429
+ })
430
+ }
431
+ })
432
+
433
+ return Array.from(assets.entries()).map(([key, quantity]) => {
434
+ const [policyId, assetName] = key.split('.')
435
+ return { policyId, assetName, quantity }
436
+ })
437
+ }
438
+
439
+ async sendAsset(toAddress: string, policyId: string, assetName: string, quantity: string) {
440
+ // Send native asset logic
441
+ }
442
+ }
443
+ ```
444
+
445
+ ## 🧪 Testing Your DApp
446
+
447
+ ### Unit Testing
448
+
449
+ ```typescript
450
+ // tests/wallet.test.ts
451
+ import { AppWallet, NETWORK_ID } from '@hydrawallet/core'
452
+
453
+ describe('DApp Wallet Integration', () => {
454
+ let wallet: AppWallet
455
+
456
+ beforeEach(() => {
457
+ const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
458
+ wallet = new AppWallet({
459
+ networkId: NETWORK_ID.PREPROD,
460
+ key: { type: 'mnemonic', words: mnemonic }
461
+ })
462
+ })
463
+
464
+ test('should create wallet for DApp', () => {
465
+ expect(wallet).toBeDefined()
466
+
467
+ const account = wallet.getAccount(0, 0)
468
+ expect(account.address).toBeTruthy()
469
+ expect(account.publicKey).toBeTruthy()
470
+ })
471
+
472
+ test('should generate multiple accounts', () => {
473
+ const accounts = []
474
+ for (let i = 0; i < 3; i++) {
475
+ accounts.push(wallet.getAccount(0, i))
476
+ }
477
+
478
+ expect(accounts).toHaveLength(3)
479
+ expect(new Set(accounts.map(a => a.address)).size).toBe(3)
480
+ })
481
+ })
482
+ ```
483
+
484
+ ### Integration Testing
485
+
486
+ ```typescript
487
+ // tests/integration.test.ts
488
+ import { WalletManager, TransactionHandler } from '../src'
489
+
490
+ describe('DApp Integration', () => {
491
+ test('should handle complete wallet flow', async () => {
492
+ const manager = new WalletManager()
493
+ const wallet = await manager.initialize()
494
+
495
+ const handler = new TransactionHandler(wallet)
496
+ const account = wallet.getAccount(0, 0)
497
+
498
+ // Test wallet creation
499
+ expect(wallet).toBeDefined()
500
+ expect(account.address).toBeTruthy()
501
+
502
+ // Test balance retrieval
503
+ const balance = await wallet.getBalance(account.address)
504
+ expect(typeof balance).toBe('string')
505
+ })
506
+ })
507
+ ```
508
+
509
+ ## 📚 Complete API Reference
510
+
511
+ ### AppWallet Class
512
+
513
+ #### Constructor
514
+ ```typescript
515
+ new AppWallet(config: WalletConfig)
516
+
517
+ interface WalletConfig {
518
+ networkId: NETWORK_ID
519
+ key: {
520
+ type: 'mnemonic' | 'private_key'
521
+ words?: string
522
+ key?: string
523
+ }
524
+ provider?: NetworkProvider
525
+ }
526
+ ```
527
+
528
+ #### Static Methods
529
+ ```typescript
530
+ // Generate new mnemonic (12, 15, 18, 21, or 24 words)
531
+ AppWallet.brew(wordCount?: number): string
532
+
533
+ // Validate mnemonic phrase
534
+ AppWallet.validateMnemonic(mnemonic: string): boolean
535
+
536
+ // Validate Cardano address
537
+ AppWallet.validateAddress(address: string): boolean
538
+
539
+ // Convert mnemonic to entropy
540
+ AppWallet.mnemonicToEntropy(mnemonic: string): string
541
+
542
+ // Convert entropy to mnemonic
543
+ AppWallet.entropyToMnemonic(entropy: string): string
544
+ ```
545
+
546
+ #### Instance Methods
547
+ ```typescript
548
+ // Account management
549
+ getAccount(accountIndex: number, addressIndex: number): Account
550
+ getPrivateKey(accountIndex: number, addressIndex: number): string
551
+
552
+ // Transaction operations
553
+ buildTransaction(params: TransactionParams): Promise<Transaction>
554
+ signTransaction(transaction: Transaction): Promise<SignedTransaction>
555
+ submitTransaction(signedTx: SignedTransaction): Promise<string>
556
+
557
+ // Blockchain queries
558
+ getUtxos(address: string): Promise<UTXO[]>
559
+ getBalance(address: string): Promise<string>
560
+ getTransactionHistory(address: string): Promise<Transaction[]>
561
+ getTransaction(txHash: string): Promise<TransactionDetails>
562
+
563
+ // Asset operations
564
+ getAssets(address: string): Promise<Asset[]>
565
+ sendAsset(params: AssetTransferParams): Promise<string>
566
+ ```
567
+
568
+ ### Type Definitions
569
+
570
+ ```typescript
571
+ interface Account {
572
+ address: string
573
+ publicKey: string
574
+ accountIndex: number
575
+ addressIndex: number
576
+ }
577
+
578
+ interface UTXO {
579
+ txHash: string
580
+ outputIndex: number
581
+ amount: string
582
+ address: string
583
+ assets?: Asset[]
584
+ }
585
+
586
+ interface Asset {
587
+ policyId: string
588
+ assetName: string
589
+ quantity: string
590
+ }
591
+
592
+ interface TransactionParams {
593
+ outputs: {
594
+ address: string
595
+ amount: string
596
+ assets?: Asset[]
597
+ }[]
598
+ changeAddress: string
599
+ metadata?: any
600
+ }
601
+
602
+ enum NETWORK_ID {
603
+ MAINNET = 1,
604
+ TESTNET = 0,
605
+ PREPROD = 0
606
+ }
607
+ ```
608
+
609
+ ## 🔧 Configuration
610
+
611
+ ### Environment Variables for DApps
612
+
613
+ ```bash
614
+ # Network Configuration
615
+ VITE_CARDANO_NETWORK=preprod
616
+ VITE_BLOCKFROST_PROJECT_ID=your_project_id
617
+
618
+ # DApp Configuration
619
+ VITE_DAPP_NAME="My Cardano DApp"
620
+ VITE_DAPP_URL=https://mydapp.com
621
+
622
+ # Development
623
+ VITE_DEBUG_MODE=true
624
+ ```
625
+
626
+ ### Vite Environment Setup
627
+
628
+ ```typescript
629
+ // vite-env.d.ts
630
+ interface ImportMetaEnv {
631
+ readonly VITE_CARDANO_NETWORK: string
632
+ readonly VITE_BLOCKFROST_PROJECT_ID: string
633
+ readonly VITE_DAPP_NAME: string
634
+ readonly VITE_DAPP_URL: string
635
+ readonly VITE_DEBUG_MODE: string
636
+ }
637
+
638
+ interface ImportMeta {
639
+ readonly env: ImportMetaEnv
640
+ }
641
+ ```
642
+
643
+ ## 🚀 Deployment for DApps
644
+
645
+ ### Build Configuration
646
+
647
+ ```json
648
+ {
649
+ "scripts": {
650
+ "dev": "vite",
651
+ "build": "vite build",
652
+ "preview": "vite preview",
653
+ "deploy": "npm run build && npm run deploy:ipfs"
654
+ }
655
+ }
656
+ ```
657
+
658
+ ### IPFS Deployment
659
+
660
+ ```bash
661
+ # Build for production
662
+ npm run build
663
+
664
+ # Deploy to IPFS
665
+ ipfs add -r dist/
666
+
667
+ # Or use services like Fleek, Pinata
668
+ ```
669
+
670
+ ## 🤝 Contributing
671
+
672
+ ### Development Setup
673
+
674
+ ```bash
675
+ # Clone repository
676
+ git clone https://github.com/aniadev/hydra-wallet-sdk.git
677
+ cd hydra-wallet-sdk
678
+
679
+ # Install dependencies
680
+ pnpm install
681
+
682
+ # Build packages
683
+ pnpm build:packages
684
+
685
+ # Run tests
686
+ pnpm --filter @hydrawallet/core test
687
+
688
+ # Start development
689
+ pnpm --filter @hydrawallet/core dev
690
+ ```
691
+
692
+ ## 📄 License
693
+
694
+ MIT License - see [LICENSE](../../LICENSE) file for details.
695
+
696
+ ## 🔗 Related Resources
697
+
698
+ - **Packages**:
699
+ - [`@hydrawallet-sdk/cardano-wasm`](../cardano-wasm/README.md) - Cardano WASM bindings
700
+ - [`@hydrawallet-sdk/transaction`](../hydrawallet-transaction/README.md) - Transaction utilities
701
+ - **Documentation**: [Hydra Wallet SDK Docs](https://hydrawallet-sdk.dev)
702
+ - **Examples**: [DApp Examples](../../examples/)
703
+ - **Community**: [Discord](https://discord.gg/hydrawallet)
704
+
705
+ ---
706
+
707
+ **@hydrawallet/core** - The essential Cardano wallet SDK for browser DApps with Vite & Rollup support
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hydrawallet-sdk/core",
3
3
  "license": "MIT",
4
- "version": "0.0.2",
4
+ "version": "0.0.3",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -45,7 +45,7 @@
45
45
  "dependencies": {
46
46
  "@scure/base": "^1.2.6",
47
47
  "bip39": "3.1.0",
48
- "@hydrawallet-sdk/cardano-wasm": "0.0.2"
48
+ "@hydrawallet-sdk/cardano-wasm": "0.0.3"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "tsup && tsc --emitDeclarationOnly --declaration --outDir dist",