@sip-protocol/react-native 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +186 -0
- package/dist/index.d.mts +442 -0
- package/dist/index.d.ts +442 -0
- package/dist/index.js +612 -0
- package/dist/index.mjs +575 -0
- package/package.json +86 -0
- package/src/hooks/index.ts +30 -0
- package/src/hooks/use-scan-payments.ts +288 -0
- package/src/hooks/use-stealth-address.ts +329 -0
- package/src/hooks/use-stealth-transfer.ts +252 -0
- package/src/index.ts +58 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/secure-storage.ts +395 -0
- package/src/utils/clipboard.ts +67 -0
- package/src/utils/index.ts +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 RECTOR Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# @sip-protocol/react-native
|
|
2
|
+
|
|
3
|
+
React Native SDK for Shielded Intents Protocol - privacy on iOS/Android.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @sip-protocol/react-native @sip-protocol/sdk
|
|
9
|
+
|
|
10
|
+
# Required peer dependencies
|
|
11
|
+
npm install react react-native
|
|
12
|
+
|
|
13
|
+
# Optional: For secure key storage (recommended for production)
|
|
14
|
+
npm install react-native-keychain
|
|
15
|
+
|
|
16
|
+
# Optional: For clipboard functionality
|
|
17
|
+
npm install @react-native-clipboard/clipboard
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- **Mobile-optimized hooks** for stealth addresses, transfers, and payment scanning
|
|
23
|
+
- **Secure key storage** via iOS Keychain and Android Keystore
|
|
24
|
+
- **Biometric authentication** support for key access
|
|
25
|
+
- **Native clipboard** integration
|
|
26
|
+
- **Same API** as `@sip-protocol/react` with mobile-specific enhancements
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import {
|
|
32
|
+
useStealthAddress,
|
|
33
|
+
useStealthTransfer,
|
|
34
|
+
useScanPayments,
|
|
35
|
+
SecureStorage,
|
|
36
|
+
} from '@sip-protocol/react-native'
|
|
37
|
+
|
|
38
|
+
function ReceiveScreen() {
|
|
39
|
+
const {
|
|
40
|
+
metaAddress,
|
|
41
|
+
stealthAddress,
|
|
42
|
+
copyToClipboard,
|
|
43
|
+
saveToKeychain,
|
|
44
|
+
} = useStealthAddress('solana', {
|
|
45
|
+
autoSave: true,
|
|
46
|
+
requireBiometrics: true,
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<View>
|
|
51
|
+
<Text>Share this address:</Text>
|
|
52
|
+
<Text selectable>{metaAddress}</Text>
|
|
53
|
+
|
|
54
|
+
<TouchableOpacity onPress={copyToClipboard}>
|
|
55
|
+
<Text>Copy to Clipboard</Text>
|
|
56
|
+
</TouchableOpacity>
|
|
57
|
+
|
|
58
|
+
<TouchableOpacity onPress={saveToKeychain}>
|
|
59
|
+
<Text>Save to Keychain</Text>
|
|
60
|
+
</TouchableOpacity>
|
|
61
|
+
</View>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Hooks
|
|
67
|
+
|
|
68
|
+
### useStealthAddress
|
|
69
|
+
|
|
70
|
+
Generate and manage stealth addresses with secure storage.
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
const {
|
|
74
|
+
metaAddress, // Encoded meta-address for sharing
|
|
75
|
+
stealthAddress, // One-time stealth address
|
|
76
|
+
spendingPrivateKey, // For claiming (handle securely!)
|
|
77
|
+
viewingPrivateKey, // For scanning
|
|
78
|
+
isGenerating, // Loading state
|
|
79
|
+
error, // Error if any
|
|
80
|
+
regenerate, // Generate new stealth address
|
|
81
|
+
copyToClipboard, // Copy to native clipboard
|
|
82
|
+
saveToKeychain, // Save keys securely
|
|
83
|
+
loadFromKeychain, // Load keys from storage
|
|
84
|
+
} = useStealthAddress('solana', {
|
|
85
|
+
autoSave: false, // Auto-save on generation
|
|
86
|
+
requireBiometrics: true, // Require FaceID/TouchID
|
|
87
|
+
walletId: 'main', // Storage identifier
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### useStealthTransfer
|
|
92
|
+
|
|
93
|
+
Execute private SPL token transfers.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
const {
|
|
97
|
+
transfer,
|
|
98
|
+
status, // 'idle' | 'preparing' | 'signing' | 'sending' | 'confirming' | 'success' | 'error'
|
|
99
|
+
error,
|
|
100
|
+
isLoading,
|
|
101
|
+
reset,
|
|
102
|
+
} = useStealthTransfer({
|
|
103
|
+
connection,
|
|
104
|
+
wallet: walletAdapter,
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
// Send private payment
|
|
108
|
+
const result = await transfer({
|
|
109
|
+
recipientMetaAddress: 'sip:solana:...',
|
|
110
|
+
amount: 1000000n, // 1 USDC
|
|
111
|
+
mint: USDC_MINT,
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
if (result.success) {
|
|
115
|
+
Alert.alert('Success', `Sent to ${result.stealthAddress}`)
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### useScanPayments
|
|
120
|
+
|
|
121
|
+
Scan for incoming private payments.
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
const {
|
|
125
|
+
payments, // Array of received payments
|
|
126
|
+
isScanning,
|
|
127
|
+
scan, // (viewingKey, spendingPubKey) => Promise<void>
|
|
128
|
+
claim, // (signature, spendingKey, destination) => Promise<string>
|
|
129
|
+
claimAll, // (spendingKey, destination) => Promise<string[]>
|
|
130
|
+
clear,
|
|
131
|
+
} = useScanPayments({
|
|
132
|
+
connection,
|
|
133
|
+
provider: heliusProvider, // Optional, recommended for efficiency
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
// Scan for payments
|
|
137
|
+
await scan(viewingPrivateKey, spendingPublicKey)
|
|
138
|
+
|
|
139
|
+
// Claim a payment
|
|
140
|
+
await claim(payment.signature, spendingPrivateKey, myWalletAddress)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Secure Storage
|
|
144
|
+
|
|
145
|
+
The `SecureStorage` API provides platform-native secure storage:
|
|
146
|
+
|
|
147
|
+
- **iOS**: Keychain with optional biometric protection
|
|
148
|
+
- **Android**: Keystore with optional biometric protection
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { SecureStorage } from '@sip-protocol/react-native'
|
|
152
|
+
|
|
153
|
+
// Store viewing key
|
|
154
|
+
await SecureStorage.setViewingKey('wallet-1', viewingKey, {
|
|
155
|
+
requireBiometrics: true,
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// Retrieve with biometric prompt
|
|
159
|
+
const key = await SecureStorage.getViewingKey('wallet-1', {
|
|
160
|
+
requireBiometrics: true,
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
// Check biometrics support
|
|
164
|
+
const { available, biometryType } = await SecureStorage.getSupportedBiometrics()
|
|
165
|
+
// biometryType: 'FaceID' | 'TouchID' | 'Fingerprint' | 'None'
|
|
166
|
+
|
|
167
|
+
// Clear all keys on logout
|
|
168
|
+
await SecureStorage.clearAll()
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Platform Requirements
|
|
172
|
+
|
|
173
|
+
- iOS 13.0+
|
|
174
|
+
- Android API 23+
|
|
175
|
+
- React Native 0.71+
|
|
176
|
+
|
|
177
|
+
## Security Considerations
|
|
178
|
+
|
|
179
|
+
1. **Always use biometrics** for spending key access in production
|
|
180
|
+
2. **Never log private keys** - use `SecureStorage` for persistence
|
|
181
|
+
3. **Clear keys on logout** - call `SecureStorage.clearAll()`
|
|
182
|
+
4. **Use auto-lock** - keys are protected by device lock state
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
export { Asset, ChainId, HexString, PrivacyLevel } from '@sip-protocol/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* useStealthAddress - Mobile-optimized stealth address hook
|
|
5
|
+
*
|
|
6
|
+
* React Native version with secure storage and native clipboard support.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import { useStealthAddress } from '@sip-protocol/react-native'
|
|
11
|
+
*
|
|
12
|
+
* function ReceiveScreen() {
|
|
13
|
+
* const {
|
|
14
|
+
* metaAddress,
|
|
15
|
+
* stealthAddress,
|
|
16
|
+
* isGenerating,
|
|
17
|
+
* regenerate,
|
|
18
|
+
* copyToClipboard,
|
|
19
|
+
* saveToKeychain,
|
|
20
|
+
* } = useStealthAddress('solana')
|
|
21
|
+
*
|
|
22
|
+
* return (
|
|
23
|
+
* <View>
|
|
24
|
+
* <Text>Share: {metaAddress}</Text>
|
|
25
|
+
* <TouchableOpacity onPress={copyToClipboard}>
|
|
26
|
+
* <Text>Copy</Text>
|
|
27
|
+
* </TouchableOpacity>
|
|
28
|
+
* <TouchableOpacity onPress={saveToKeychain}>
|
|
29
|
+
* <Text>Save Securely</Text>
|
|
30
|
+
* </TouchableOpacity>
|
|
31
|
+
* </View>
|
|
32
|
+
* )
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* Supported chain IDs (matches @sip-protocol/types ChainId)
|
|
38
|
+
*/
|
|
39
|
+
type SupportedChainId = 'ethereum' | 'solana' | 'near' | 'bitcoin' | 'polygon' | 'arbitrum' | 'optimism' | 'base' | 'bsc' | 'avalanche' | 'cosmos' | 'aptos' | 'sui' | 'polkadot' | 'tezos';
|
|
40
|
+
/**
|
|
41
|
+
* Options for useStealthAddress hook
|
|
42
|
+
*/
|
|
43
|
+
interface UseStealthAddressOptions {
|
|
44
|
+
/** Auto-save to secure storage on generation */
|
|
45
|
+
autoSave?: boolean;
|
|
46
|
+
/** Require biometrics to access stored keys */
|
|
47
|
+
requireBiometrics?: boolean;
|
|
48
|
+
/** Wallet identifier for storage (default: 'default') */
|
|
49
|
+
walletId?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Return type for useStealthAddress hook
|
|
53
|
+
*/
|
|
54
|
+
interface UseStealthAddressReturn {
|
|
55
|
+
/** Encoded meta-address for sharing */
|
|
56
|
+
metaAddress: string | null;
|
|
57
|
+
/** One-time stealth address */
|
|
58
|
+
stealthAddress: string | null;
|
|
59
|
+
/** Spending private key (for claiming) */
|
|
60
|
+
spendingPrivateKey: string | null;
|
|
61
|
+
/** Viewing private key (for scanning) */
|
|
62
|
+
viewingPrivateKey: string | null;
|
|
63
|
+
/** Whether generation is in progress */
|
|
64
|
+
isGenerating: boolean;
|
|
65
|
+
/** Error if any occurred */
|
|
66
|
+
error: Error | null;
|
|
67
|
+
/** Generate a new stealth address */
|
|
68
|
+
regenerate: () => void;
|
|
69
|
+
/** Copy stealth address to clipboard */
|
|
70
|
+
copyToClipboard: () => Promise<boolean>;
|
|
71
|
+
/** Save keys to secure storage */
|
|
72
|
+
saveToKeychain: () => Promise<boolean>;
|
|
73
|
+
/** Load keys from secure storage */
|
|
74
|
+
loadFromKeychain: () => Promise<boolean>;
|
|
75
|
+
/** Clear error state */
|
|
76
|
+
clearError: () => void;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Mobile-optimized stealth address hook
|
|
80
|
+
*
|
|
81
|
+
* @param chain - Target blockchain
|
|
82
|
+
* @param options - Hook options
|
|
83
|
+
*/
|
|
84
|
+
declare function useStealthAddress(chain: SupportedChainId, options?: UseStealthAddressOptions): UseStealthAddressReturn;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* useStealthTransfer - Mobile-optimized private transfer hook
|
|
88
|
+
*
|
|
89
|
+
* Handles shielded SPL token transfers on Solana from mobile devices.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```tsx
|
|
93
|
+
* import { useStealthTransfer } from '@sip-protocol/react-native'
|
|
94
|
+
*
|
|
95
|
+
* function SendScreen() {
|
|
96
|
+
* const { transfer, status, error, isLoading } = useStealthTransfer({
|
|
97
|
+
* connection,
|
|
98
|
+
* wallet: walletAdapter,
|
|
99
|
+
* })
|
|
100
|
+
*
|
|
101
|
+
* const handleSend = async () => {
|
|
102
|
+
* const result = await transfer({
|
|
103
|
+
* recipientMetaAddress: 'sip:solana:...',
|
|
104
|
+
* amount: 1000000n, // 1 USDC
|
|
105
|
+
* mint: USDC_MINT,
|
|
106
|
+
* })
|
|
107
|
+
* if (result.success) {
|
|
108
|
+
* Alert.alert('Success', 'Payment sent privately!')
|
|
109
|
+
* }
|
|
110
|
+
* }
|
|
111
|
+
*
|
|
112
|
+
* return (
|
|
113
|
+
* <TouchableOpacity onPress={handleSend} disabled={isLoading}>
|
|
114
|
+
* <Text>{isLoading ? 'Sending...' : 'Send Private Payment'}</Text>
|
|
115
|
+
* </TouchableOpacity>
|
|
116
|
+
* )
|
|
117
|
+
* }
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
/**
|
|
121
|
+
* Wallet adapter interface for mobile wallets
|
|
122
|
+
*/
|
|
123
|
+
interface MobileWalletAdapter {
|
|
124
|
+
publicKey: {
|
|
125
|
+
toBase58(): string;
|
|
126
|
+
} | null;
|
|
127
|
+
signTransaction: <T>(transaction: T) => Promise<T>;
|
|
128
|
+
signAllTransactions?: <T>(transactions: T[]) => Promise<T[]>;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Transfer status enum
|
|
132
|
+
*/
|
|
133
|
+
type TransferStatus = 'idle' | 'preparing' | 'signing' | 'sending' | 'confirming' | 'success' | 'error';
|
|
134
|
+
/**
|
|
135
|
+
* Parameters for stealth transfer
|
|
136
|
+
*/
|
|
137
|
+
interface TransferParams {
|
|
138
|
+
/** Recipient's stealth meta-address */
|
|
139
|
+
recipientMetaAddress: string;
|
|
140
|
+
/** Amount in smallest units */
|
|
141
|
+
amount: bigint;
|
|
142
|
+
/** SPL token mint address */
|
|
143
|
+
mint: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Result of stealth transfer
|
|
147
|
+
*/
|
|
148
|
+
interface TransferResult {
|
|
149
|
+
success: boolean;
|
|
150
|
+
signature?: string;
|
|
151
|
+
stealthAddress?: string;
|
|
152
|
+
error?: Error;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Connection interface (subset of @solana/web3.js Connection)
|
|
156
|
+
*/
|
|
157
|
+
interface SolanaConnection$1 {
|
|
158
|
+
confirmTransaction(signature: string, commitment?: string): Promise<{
|
|
159
|
+
value: {
|
|
160
|
+
err: unknown;
|
|
161
|
+
};
|
|
162
|
+
}>;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Parameters for useStealthTransfer hook
|
|
166
|
+
*/
|
|
167
|
+
interface UseStealthTransferParams {
|
|
168
|
+
/** Solana connection */
|
|
169
|
+
connection: SolanaConnection$1;
|
|
170
|
+
/** Wallet adapter */
|
|
171
|
+
wallet: MobileWalletAdapter;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Return type for useStealthTransfer hook
|
|
175
|
+
*/
|
|
176
|
+
interface UseStealthTransferReturn {
|
|
177
|
+
/** Execute a private transfer */
|
|
178
|
+
transfer: (params: TransferParams) => Promise<TransferResult>;
|
|
179
|
+
/** Current transfer status */
|
|
180
|
+
status: TransferStatus;
|
|
181
|
+
/** Error if any occurred */
|
|
182
|
+
error: Error | null;
|
|
183
|
+
/** Whether a transfer is in progress */
|
|
184
|
+
isLoading: boolean;
|
|
185
|
+
/** Reset the hook state */
|
|
186
|
+
reset: () => void;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Mobile-optimized stealth transfer hook
|
|
190
|
+
*
|
|
191
|
+
* @param params - Hook parameters
|
|
192
|
+
*/
|
|
193
|
+
declare function useStealthTransfer(params: UseStealthTransferParams): UseStealthTransferReturn;
|
|
194
|
+
/**
|
|
195
|
+
* Get associated token address helper
|
|
196
|
+
*
|
|
197
|
+
* Dynamically imports from @solana/spl-token
|
|
198
|
+
*
|
|
199
|
+
* @param mint - Token mint address string
|
|
200
|
+
* @param owner - Owner address string
|
|
201
|
+
* @returns Associated token address
|
|
202
|
+
*/
|
|
203
|
+
declare function getAssociatedTokenAddress(mint: string, owner: string): Promise<string>;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* useScanPayments - Mobile-optimized payment scanning hook
|
|
207
|
+
*
|
|
208
|
+
* Scans for incoming stealth payments using viewing key.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```tsx
|
|
212
|
+
* import { useScanPayments } from '@sip-protocol/react-native'
|
|
213
|
+
*
|
|
214
|
+
* function InboxScreen() {
|
|
215
|
+
* const { payments, isScanning, scan, claim } = useScanPayments({
|
|
216
|
+
* connection,
|
|
217
|
+
* provider: heliusProvider,
|
|
218
|
+
* })
|
|
219
|
+
*
|
|
220
|
+
* useEffect(() => {
|
|
221
|
+
* // Load keys from keychain and scan
|
|
222
|
+
* loadKeysAndScan()
|
|
223
|
+
* }, [])
|
|
224
|
+
*
|
|
225
|
+
* return (
|
|
226
|
+
* <FlatList
|
|
227
|
+
* data={payments}
|
|
228
|
+
* renderItem={({ item }) => (
|
|
229
|
+
* <PaymentCard
|
|
230
|
+
* payment={item}
|
|
231
|
+
* onClaim={() => claim(item.signature)}
|
|
232
|
+
* />
|
|
233
|
+
* )}
|
|
234
|
+
* />
|
|
235
|
+
* )
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
/**
|
|
240
|
+
* Solana connection interface (subset of @solana/web3.js Connection)
|
|
241
|
+
*/
|
|
242
|
+
interface SolanaConnection {
|
|
243
|
+
getAccountInfo(publicKey: unknown): Promise<unknown>;
|
|
244
|
+
getSignaturesForAddress(address: unknown, options?: unknown): Promise<unknown[]>;
|
|
245
|
+
getTransaction(signature: string, options?: unknown): Promise<unknown>;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Scanned payment info
|
|
249
|
+
*/
|
|
250
|
+
interface ScannedPayment {
|
|
251
|
+
/** Transaction signature */
|
|
252
|
+
signature: string;
|
|
253
|
+
/** Stealth address that received the payment */
|
|
254
|
+
stealthAddress: string;
|
|
255
|
+
/** Ephemeral public key */
|
|
256
|
+
ephemeralPublicKey: string;
|
|
257
|
+
/** Token mint address */
|
|
258
|
+
mint: string;
|
|
259
|
+
/** Amount in smallest units */
|
|
260
|
+
amount: bigint;
|
|
261
|
+
/** Block timestamp */
|
|
262
|
+
timestamp: number;
|
|
263
|
+
/** Whether this payment has been claimed */
|
|
264
|
+
claimed: boolean;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Scan status
|
|
268
|
+
*/
|
|
269
|
+
type ScanStatus = 'idle' | 'scanning' | 'claiming' | 'error';
|
|
270
|
+
/**
|
|
271
|
+
* Hook parameters
|
|
272
|
+
*/
|
|
273
|
+
interface UseScanPaymentsParams {
|
|
274
|
+
/** Solana connection */
|
|
275
|
+
connection: SolanaConnection;
|
|
276
|
+
/** RPC provider (Helius recommended) */
|
|
277
|
+
provider?: unknown;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Hook return type
|
|
281
|
+
*/
|
|
282
|
+
interface UseScanPaymentsReturn {
|
|
283
|
+
/** Scanned payments */
|
|
284
|
+
payments: ScannedPayment[];
|
|
285
|
+
/** Current status */
|
|
286
|
+
status: ScanStatus;
|
|
287
|
+
/** Error if any */
|
|
288
|
+
error: Error | null;
|
|
289
|
+
/** Whether scanning is in progress */
|
|
290
|
+
isScanning: boolean;
|
|
291
|
+
/** Scan for payments */
|
|
292
|
+
scan: (viewingPrivateKey: string, spendingPublicKey: string) => Promise<void>;
|
|
293
|
+
/** Claim a specific payment */
|
|
294
|
+
claim: (signature: string, spendingPrivateKey: string, destinationAddress: string) => Promise<string | null>;
|
|
295
|
+
/** Claim all unclaimed payments */
|
|
296
|
+
claimAll: (spendingPrivateKey: string, destinationAddress: string) => Promise<string[]>;
|
|
297
|
+
/** Clear payments */
|
|
298
|
+
clear: () => void;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Mobile payment scanning hook
|
|
302
|
+
*/
|
|
303
|
+
declare function useScanPayments(params: UseScanPaymentsParams): UseScanPaymentsReturn;
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Secure Key Storage for React Native
|
|
307
|
+
*
|
|
308
|
+
* Provides secure storage for private keys using native platform capabilities:
|
|
309
|
+
* - iOS: Keychain with biometric protection
|
|
310
|
+
* - Android: Keystore with biometric protection
|
|
311
|
+
*
|
|
312
|
+
* Falls back to in-memory storage if react-native-keychain is not available.
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* ```typescript
|
|
316
|
+
* import { SecureStorage } from '@sip-protocol/react-native'
|
|
317
|
+
*
|
|
318
|
+
* // Store viewing key
|
|
319
|
+
* await SecureStorage.setViewingKey('my-wallet', viewingPrivateKey)
|
|
320
|
+
*
|
|
321
|
+
* // Retrieve with biometric prompt
|
|
322
|
+
* const key = await SecureStorage.getViewingKey('my-wallet')
|
|
323
|
+
*
|
|
324
|
+
* // Clear on logout
|
|
325
|
+
* await SecureStorage.clearAll()
|
|
326
|
+
* ```
|
|
327
|
+
*/
|
|
328
|
+
/**
|
|
329
|
+
* Storage options for secure key storage
|
|
330
|
+
*/
|
|
331
|
+
interface SecureStorageOptions {
|
|
332
|
+
/** Key identifier/service name */
|
|
333
|
+
service?: string;
|
|
334
|
+
/** Require biometric authentication to access */
|
|
335
|
+
requireBiometrics?: boolean;
|
|
336
|
+
/** iOS: Accessibility level */
|
|
337
|
+
accessible?: 'whenUnlocked' | 'afterFirstUnlock' | 'always';
|
|
338
|
+
/** Storage backend to use */
|
|
339
|
+
backend?: 'keychain' | 'memory';
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Key prefixes for different key types
|
|
343
|
+
*/
|
|
344
|
+
declare const KEY_PREFIXES: {
|
|
345
|
+
readonly spending: "sip:spending:";
|
|
346
|
+
readonly viewing: "sip:viewing:";
|
|
347
|
+
readonly ephemeral: "sip:ephemeral:";
|
|
348
|
+
readonly meta: "sip:meta:";
|
|
349
|
+
};
|
|
350
|
+
type KeyType = keyof typeof KEY_PREFIXES;
|
|
351
|
+
/**
|
|
352
|
+
* Store a key securely
|
|
353
|
+
*
|
|
354
|
+
* @param type - Type of key (spending, viewing, ephemeral, meta)
|
|
355
|
+
* @param identifier - Unique identifier (e.g., wallet address)
|
|
356
|
+
* @param value - Key value (hex string)
|
|
357
|
+
* @param options - Storage options
|
|
358
|
+
*/
|
|
359
|
+
declare function setKey(type: KeyType, identifier: string, value: string, options?: SecureStorageOptions): Promise<boolean>;
|
|
360
|
+
/**
|
|
361
|
+
* Retrieve a key from secure storage
|
|
362
|
+
*
|
|
363
|
+
* @param type - Type of key (spending, viewing, ephemeral, meta)
|
|
364
|
+
* @param identifier - Unique identifier (e.g., wallet address)
|
|
365
|
+
* @param options - Storage options
|
|
366
|
+
* @returns Key value or null if not found
|
|
367
|
+
*/
|
|
368
|
+
declare function getKey(type: KeyType, identifier: string, options?: SecureStorageOptions): Promise<string | null>;
|
|
369
|
+
/**
|
|
370
|
+
* Delete a key from secure storage
|
|
371
|
+
*
|
|
372
|
+
* @param type - Type of key (spending, viewing, ephemeral, meta)
|
|
373
|
+
* @param identifier - Unique identifier (e.g., wallet address)
|
|
374
|
+
* @param options - Storage options
|
|
375
|
+
*/
|
|
376
|
+
declare function deleteKey(type: KeyType, identifier: string, options?: SecureStorageOptions): Promise<boolean>;
|
|
377
|
+
/**
|
|
378
|
+
* Clear all stored keys
|
|
379
|
+
*
|
|
380
|
+
* @param options - Storage options
|
|
381
|
+
*/
|
|
382
|
+
declare function clearAll(options?: SecureStorageOptions): Promise<boolean>;
|
|
383
|
+
/**
|
|
384
|
+
* Check if biometrics are available on this device
|
|
385
|
+
*
|
|
386
|
+
* @returns Biometrics support info
|
|
387
|
+
*/
|
|
388
|
+
declare function getSupportedBiometrics(): Promise<{
|
|
389
|
+
available: boolean;
|
|
390
|
+
biometryType: 'FaceID' | 'TouchID' | 'Fingerprint' | 'None';
|
|
391
|
+
}>;
|
|
392
|
+
/**
|
|
393
|
+
* Check if secure storage is available
|
|
394
|
+
*/
|
|
395
|
+
declare function isAvailable(): boolean;
|
|
396
|
+
/**
|
|
397
|
+
* SecureStorage API
|
|
398
|
+
*
|
|
399
|
+
* Unified API for secure key storage on mobile devices.
|
|
400
|
+
*/
|
|
401
|
+
declare const SecureStorage: {
|
|
402
|
+
readonly setKey: typeof setKey;
|
|
403
|
+
readonly getKey: typeof getKey;
|
|
404
|
+
readonly deleteKey: typeof deleteKey;
|
|
405
|
+
readonly clearAll: typeof clearAll;
|
|
406
|
+
readonly setViewingKey: (identifier: string, key: string, options?: SecureStorageOptions) => Promise<boolean>;
|
|
407
|
+
readonly getViewingKey: (identifier: string, options?: SecureStorageOptions) => Promise<string | null>;
|
|
408
|
+
readonly deleteViewingKey: (identifier: string, options?: SecureStorageOptions) => Promise<boolean>;
|
|
409
|
+
readonly setSpendingKey: (identifier: string, key: string, options?: SecureStorageOptions) => Promise<boolean>;
|
|
410
|
+
readonly getSpendingKey: (identifier: string, options?: SecureStorageOptions) => Promise<string | null>;
|
|
411
|
+
readonly deleteSpendingKey: (identifier: string, options?: SecureStorageOptions) => Promise<boolean>;
|
|
412
|
+
readonly setMetaAddress: (identifier: string, meta: string, options?: SecureStorageOptions) => Promise<boolean>;
|
|
413
|
+
readonly getMetaAddress: (identifier: string, options?: SecureStorageOptions) => Promise<string | null>;
|
|
414
|
+
readonly deleteMetaAddress: (identifier: string, options?: SecureStorageOptions) => Promise<boolean>;
|
|
415
|
+
readonly getSupportedBiometrics: typeof getSupportedBiometrics;
|
|
416
|
+
readonly isAvailable: typeof isAvailable;
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Clipboard Utilities for React Native
|
|
421
|
+
*
|
|
422
|
+
* Provides cross-platform clipboard access with fallback support.
|
|
423
|
+
*/
|
|
424
|
+
/**
|
|
425
|
+
* Copy text to clipboard
|
|
426
|
+
*
|
|
427
|
+
* @param text - Text to copy
|
|
428
|
+
* @returns true if successful
|
|
429
|
+
*/
|
|
430
|
+
declare function copyToClipboard(text: string): Promise<boolean>;
|
|
431
|
+
/**
|
|
432
|
+
* Read text from clipboard
|
|
433
|
+
*
|
|
434
|
+
* @returns Clipboard contents or empty string
|
|
435
|
+
*/
|
|
436
|
+
declare function readFromClipboard(): Promise<string>;
|
|
437
|
+
/**
|
|
438
|
+
* Check if clipboard is available
|
|
439
|
+
*/
|
|
440
|
+
declare function isClipboardAvailable(): boolean;
|
|
441
|
+
|
|
442
|
+
export { type KeyType, type MobileWalletAdapter, type ScanStatus, type ScannedPayment, SecureStorage, type SecureStorageOptions, type TransferParams, type TransferResult, type TransferStatus, type UseScanPaymentsParams, type UseScanPaymentsReturn, type UseStealthAddressOptions, type UseStealthAddressReturn, type UseStealthTransferParams, type UseStealthTransferReturn, copyToClipboard, getAssociatedTokenAddress, isClipboardAvailable, readFromClipboard, useScanPayments, useStealthAddress, useStealthTransfer };
|