@solana-mobile/seed-vault-lib 0.2.0 → 0.3.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.
@@ -73,7 +73,7 @@ internal fun SeedVaultEvent.toWritableMap() : WritableMap = Arguments.createMap(
73
73
  Arguments.createMap().apply {
74
74
  putArray("publicKey", response.publicKey.toWritableArray())
75
75
  putString("publicKeyEncoded", response.publicKeyEncoded)
76
- putString("resolvedDerviationPath", response.resolvedDerivationPath.toString())
76
+ putString("resolvedDerivationPath", response.resolvedDerivationPath.toString())
77
77
  }
78
78
  }))
79
79
  }
@@ -2,6 +2,7 @@ package com.solanamobile.seedvault.reactnative
2
2
 
3
3
  import android.app.Activity;
4
4
  import android.content.Intent;
5
+ import android.content.pm.PackageManager
5
6
  import android.database.ContentObserver
6
7
  import android.net.Uri
7
8
  import android.os.Bundle
@@ -43,7 +44,10 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
43
44
  init {
44
45
  reactContext.addActivityEventListener(mActivityEventListener)
45
46
 
46
- observeSeedVaultContentChanges()
47
+ if (reactContext.checkSelfPermission(WalletContractV1.PERMISSION_ACCESS_SEED_VAULT) == PackageManager.PERMISSION_GRANTED &&
48
+ SeedVault.isAvailable(reactContext, true)) {
49
+ observeSeedVaultContentChanges()
50
+ }
47
51
  }
48
52
 
49
53
  @ReactMethod
@@ -62,9 +66,17 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
62
66
 
63
67
  @ReactMethod
64
68
  fun hasUnauthorizedSeeds(promise: Promise) {
69
+ hasUnauthorizedSeedsForPurpose(WalletContractV1.PURPOSE_SIGN_SOLANA_TRANSACTION, promise)
70
+ }
71
+
72
+ @ReactMethod
73
+ fun hasUnauthorizedSeedsForPurpose(purpose: Double, promise: Promise) {
74
+ hasUnauthorizedSeedsForPurpose(purpose.toInt(), promise)
75
+ }
76
+
77
+ private fun hasUnauthorizedSeedsForPurpose(purpose: Int, promise: Promise) {
65
78
  val application = reactContext.currentActivity?.application!!
66
- val hasUnauthorizedSeeds = Wallet.hasUnauthorizedSeedsForPurpose(application,
67
- WalletContractV1.PURPOSE_SIGN_SOLANA_TRANSACTION)
79
+ val hasUnauthorizedSeeds = Wallet.hasUnauthorizedSeedsForPurpose(application, purpose)
68
80
  promise.resolve(hasUnauthorizedSeeds)
69
81
  }
70
82
 
@@ -108,11 +120,10 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
108
120
  }
109
121
 
110
122
  @ReactMethod
111
- fun getAccounts(authToken: String, promise: Promise) {
123
+ fun getAccounts(authToken: String, filterOnColumn: String, value: Any, promise: Promise) {
112
124
  val application = reactContext.currentActivity?.application!!
113
125
  val accountsCursor = Wallet.getAccounts(application, authToken.toLong(),
114
- WalletContractV1.ACCOUNTS_ALL_COLUMNS,
115
- WalletContractV1.ACCOUNTS_ACCOUNT_IS_USER_WALLET, "1")!!
126
+ WalletContractV1.ACCOUNTS_ALL_COLUMNS, filterOnColumn, value)!!
116
127
 
117
128
  val accounts = mutableListOf<Account>()
118
129
 
@@ -132,6 +143,11 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
132
143
  promise.resolve(accounts.toWritableArray())
133
144
  }
134
145
 
146
+ @ReactMethod
147
+ fun getUserWallets(authToken: String, promise: Promise) {
148
+ getAccounts(authToken, WalletContractV1.ACCOUNTS_ACCOUNT_IS_USER_WALLET, "1", promise)
149
+ }
150
+
135
151
  @ReactMethod
136
152
  fun requestAuthorizeNewSeed() {
137
153
  Log.d(TAG, "Requesting authorization for a new seed...")
@@ -228,6 +244,16 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
228
244
  Log.d(TAG, "Account name updated (to '$name')")
229
245
  }
230
246
 
247
+ @ReactMethod
248
+ fun updateAccountIsUserWallet(authToken: String, accountId: String, isUserWallet: Boolean) {
249
+ Wallet.updateAccountIsUserWallet(reactContext, authToken.toLong(), accountId.toLong(), isUserWallet)
250
+ }
251
+
252
+ @ReactMethod
253
+ fun updateAccountIsValid(authToken: String, accountId: String, isValid: Boolean) {
254
+ Wallet.updateAccountIsValid(reactContext, authToken.toLong(), accountId.toLong(), isValid)
255
+ }
256
+
231
257
  @ReactMethod
232
258
  fun requestSignMessage(authToken: String, derivationPath: String, message: ReadableArray) {
233
259
  requestSignMessages(authToken, listOf(SigningRequest(message.toByteArray(), arrayListOf(Uri.parse(derivationPath)))))
@@ -419,7 +445,7 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
419
445
  Arguments.createMap().apply {
420
446
  putArray("publicKey", response.publicKey.toWritableArray())
421
447
  putString("publicKeyEncoded", response.publicKeyEncoded)
422
- putString("resolvedDerviationPath", response.resolvedDerivationPath.toString())
448
+ putString("resolvedDerivationPath", response.resolvedDerivationPath.toString())
423
449
  }
424
450
  }), null
425
451
  )
@@ -430,6 +456,21 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
430
456
  }
431
457
  }
432
458
 
459
+ @ReactMethod
460
+ fun resolveDerivationPath(derivationPath: String, promise: Promise) {
461
+ resolveDerivationPath(Uri.parse(derivationPath), WalletContractV1.PURPOSE_SIGN_SOLANA_TRANSACTION, promise)
462
+ }
463
+
464
+ @ReactMethod
465
+ fun resolveDerivationPathForPurpose(derivationPath: String, purpose: Double, promise: Promise) {
466
+ resolveDerivationPath(Uri.parse(derivationPath), purpose.toInt(), promise)
467
+ }
468
+
469
+ private fun resolveDerivationPath(derivationPath: Uri, purpose: Int, promise: Promise) {
470
+ val resolvedDerivationPath = Wallet.resolveDerivationPath(reactContext, derivationPath, purpose)
471
+ promise.resolve(resolvedDerivationPath.toString())
472
+ }
473
+
433
474
  private fun sendEvent(reactContext: ReactContext, eventName: String, params: WritableMap? = null) {
434
475
  reactContext
435
476
  .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
@@ -453,7 +494,6 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
453
494
  throw NotImplementedError("Stub for legacy onChange")
454
495
 
455
496
  override fun onChange(selfChange: Boolean, uris: Collection<Uri>, flags: Int) {
456
- Log.d(TAG, "Received change notification for $uris (flags=$flags); refreshing viewmodel")
457
497
  sendEvent(reactContext, SEED_VAULT_CONTENT_CHANGE_EVENT_BRIDGE_NAME,
458
498
  params = Arguments.createMap().apply {
459
499
  putString("__type", "SeedVaultContentChange")
@@ -542,4 +582,4 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
542
582
  private const val DEFAULT_ACTIVITY_RESULT_TIMEOUT_MS = 300000L
543
583
  private const val MINIMUM_ACTIVITY_RESULT_TIMEOUT_MS = 30000L
544
584
  }
545
- }
585
+ }
@@ -107,6 +107,7 @@ type SigningResult = Readonly<{
107
107
  }>;
108
108
  interface AuthorizeSeedAPI {
109
109
  hasUnauthorizedSeeds(): boolean;
110
+ hasUnauthorizedSeedsForPurpose(purpose: SeedPurpose): boolean;
110
111
  getAuthorizedSeeds(): Seed[];
111
112
  authorizeNewSeed(): {
112
113
  authToken: AuthToken;
@@ -114,14 +115,22 @@ interface AuthorizeSeedAPI {
114
115
  deauthorizeSeed(authToken: AuthToken): void;
115
116
  }
116
117
  interface AccountAPI {
117
- getAccounts(authToken: AuthToken): Account[];
118
+ getAccounts(authToken: AuthToken, filterOnColumn: string, value: any): Account[];
119
+ getUserWallets(authToken: AuthToken): Account[];
118
120
  updateAccountName(authToken: AuthToken, accountId: number, name?: string): void;
121
+ updateAccountIsUserWallet(authToken: AuthToken, accountId: number, isUserWallet: boolean): void;
122
+ updateAccountIsValid(authToken: AuthToken, accountId: number, isValid: boolean): void;
119
123
  }
120
124
  interface CreateNewSeedAPI {
121
125
  createNewSeed(): {
122
126
  authToken: AuthToken;
123
127
  };
124
128
  }
129
+ // TODO
130
+ // interface ImplementationLimitsAPI {
131
+ // getImplementationLimits(): void
132
+ // getImplementationLimitsForPurpose()
133
+ // }
125
134
  interface ImportExistingSeedAPI {
126
135
  importExistingSeed(): {
127
136
  authToken: AuthToken;
@@ -130,6 +139,8 @@ interface ImportExistingSeedAPI {
130
139
  interface PublicKeyAPI {
131
140
  getPublicKey(authToken: AuthToken, derivationPath: DerivationPath): SeedPublicKey;
132
141
  getPublicKeys(authToken: AuthToken, derivationPaths: DerivationPath[]): SeedPublicKey[];
142
+ resolveDerivationPath(derivationPath: DerivationPath): DerivationPath;
143
+ resolveDerivationPathForPurpose(derivationPath: DerivationPath, purpose: SeedPurpose): DerivationPath;
133
144
  }
134
145
  interface SignMessagesAPI {
135
146
  signMessage(authToken: AuthToken, derivationPath: DerivationPath, message: Base64EncodedMessage): SigningResult;
@@ -139,7 +150,10 @@ interface SignTransactionsAPI {
139
150
  signTransaction(authToken: AuthToken, derivationPath: DerivationPath, transaction: Base64EncodedTransaction): SigningResult;
140
151
  signTransactions(authToken: AuthToken, signingRequests: SigningRequest[]): SigningResult[];
141
152
  }
142
- interface SeedVaultAPI extends AuthorizeSeedAPI, AccountAPI, CreateNewSeedAPI, ImportExistingSeedAPI, PublicKeyAPI, SignMessagesAPI, SignTransactionsAPI {
153
+ interface SeedVaultAvailabilityAPI {
154
+ isSeedVaultAvailable(allowSimulated: boolean): boolean;
155
+ }
156
+ interface SeedVaultAPI extends AuthorizeSeedAPI, AccountAPI, CreateNewSeedAPI, ImportExistingSeedAPI, PublicKeyAPI, SeedVaultAvailabilityAPI, SignMessagesAPI, SignTransactionsAPI {
143
157
  }
144
158
  declare const SeedVaultPermissionAndroid: Permission;
145
159
  declare function useSeedVault(handleSeedVaultEvent: (event: SeedVaultEvent) => void, handleContentChange: (event: SeedVaultContentChange) => void): void;
@@ -107,6 +107,7 @@ type SigningResult = Readonly<{
107
107
  }>;
108
108
  interface AuthorizeSeedAPI {
109
109
  hasUnauthorizedSeeds(): boolean;
110
+ hasUnauthorizedSeedsForPurpose(purpose: SeedPurpose): boolean;
110
111
  getAuthorizedSeeds(): Seed[];
111
112
  authorizeNewSeed(): {
112
113
  authToken: AuthToken;
@@ -114,14 +115,22 @@ interface AuthorizeSeedAPI {
114
115
  deauthorizeSeed(authToken: AuthToken): void;
115
116
  }
116
117
  interface AccountAPI {
117
- getAccounts(authToken: AuthToken): Account[];
118
+ getAccounts(authToken: AuthToken, filterOnColumn: string, value: any): Account[];
119
+ getUserWallets(authToken: AuthToken): Account[];
118
120
  updateAccountName(authToken: AuthToken, accountId: number, name?: string): void;
121
+ updateAccountIsUserWallet(authToken: AuthToken, accountId: number, isUserWallet: boolean): void;
122
+ updateAccountIsValid(authToken: AuthToken, accountId: number, isValid: boolean): void;
119
123
  }
120
124
  interface CreateNewSeedAPI {
121
125
  createNewSeed(): {
122
126
  authToken: AuthToken;
123
127
  };
124
128
  }
129
+ // TODO
130
+ // interface ImplementationLimitsAPI {
131
+ // getImplementationLimits(): void
132
+ // getImplementationLimitsForPurpose()
133
+ // }
125
134
  interface ImportExistingSeedAPI {
126
135
  importExistingSeed(): {
127
136
  authToken: AuthToken;
@@ -130,6 +139,8 @@ interface ImportExistingSeedAPI {
130
139
  interface PublicKeyAPI {
131
140
  getPublicKey(authToken: AuthToken, derivationPath: DerivationPath): SeedPublicKey;
132
141
  getPublicKeys(authToken: AuthToken, derivationPaths: DerivationPath[]): SeedPublicKey[];
142
+ resolveDerivationPath(derivationPath: DerivationPath): DerivationPath;
143
+ resolveDerivationPathForPurpose(derivationPath: DerivationPath, purpose: SeedPurpose): DerivationPath;
133
144
  }
134
145
  interface SignMessagesAPI {
135
146
  signMessage(authToken: AuthToken, derivationPath: DerivationPath, message: Base64EncodedMessage): SigningResult;
@@ -139,7 +150,10 @@ interface SignTransactionsAPI {
139
150
  signTransaction(authToken: AuthToken, derivationPath: DerivationPath, transaction: Base64EncodedTransaction): SigningResult;
140
151
  signTransactions(authToken: AuthToken, signingRequests: SigningRequest[]): SigningResult[];
141
152
  }
142
- interface SeedVaultAPI extends AuthorizeSeedAPI, AccountAPI, CreateNewSeedAPI, ImportExistingSeedAPI, PublicKeyAPI, SignMessagesAPI, SignTransactionsAPI {
153
+ interface SeedVaultAvailabilityAPI {
154
+ isSeedVaultAvailable(allowSimulated: boolean): boolean;
155
+ }
156
+ interface SeedVaultAPI extends AuthorizeSeedAPI, AccountAPI, CreateNewSeedAPI, ImportExistingSeedAPI, PublicKeyAPI, SeedVaultAvailabilityAPI, SignMessagesAPI, SignTransactionsAPI {
143
157
  }
144
158
  declare const SeedVaultPermissionAndroid: Permission;
145
159
  declare function useSeedVault(handleSeedVaultEvent: (event: SeedVaultEvent) => void, handleContentChange: (event: SeedVaultContentChange) => void): void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@solana-mobile/seed-vault-lib",
3
3
  "description": "A React Native wrapper of the Solana Mobile, Seed Vault SDK. Apps can use this to interact with seed vault implementations on Android",
4
- "version": "0.2.0",
4
+ "version": "0.3.0",
5
5
  "author": "Marco Martinez <marco.martinez@solanamobile.com>",
6
6
  "repository": "https://github.com/solana-mobile/seed-vault-sdk",
7
7
  "license": "Apache-2.0",
package/src/types.ts CHANGED
@@ -48,20 +48,30 @@ export type SigningResult = Readonly<{
48
48
 
49
49
  interface AuthorizeSeedAPI {
50
50
  hasUnauthorizedSeeds(): boolean
51
+ hasUnauthorizedSeedsForPurpose(purpose: SeedPurpose): boolean
51
52
  getAuthorizedSeeds(): Seed[]
52
53
  authorizeNewSeed(): {authToken: AuthToken}
53
54
  deauthorizeSeed(authToken: AuthToken): void
54
55
  }
55
56
 
56
57
  interface AccountAPI {
57
- getAccounts(authToken: AuthToken): Account[]
58
+ getAccounts(authToken: AuthToken, filterOnColumn: string, value: any): Account[]
59
+ getUserWallets(authToken: AuthToken): Account[]
58
60
  updateAccountName(authToken: AuthToken, accountId: number, name?: string): void
61
+ updateAccountIsUserWallet(authToken: AuthToken, accountId: number, isUserWallet: boolean): void
62
+ updateAccountIsValid(authToken: AuthToken, accountId: number, isValid: boolean): void
59
63
  }
60
64
 
61
65
  interface CreateNewSeedAPI {
62
66
  createNewSeed(): {authToken: AuthToken}
63
67
  }
64
68
 
69
+ // TODO
70
+ // interface ImplementationLimitsAPI {
71
+ // getImplementationLimits(): void
72
+ // getImplementationLimitsForPurpose()
73
+ // }
74
+
65
75
  interface ImportExistingSeedAPI {
66
76
  importExistingSeed(): {authToken: AuthToken}
67
77
  }
@@ -69,6 +79,8 @@ interface ImportExistingSeedAPI {
69
79
  interface PublicKeyAPI {
70
80
  getPublicKey(authToken: AuthToken, derivationPath: DerivationPath): SeedPublicKey
71
81
  getPublicKeys(authToken: AuthToken, derivationPaths: DerivationPath[]): SeedPublicKey[]
82
+ resolveDerivationPath(derivationPath: DerivationPath): DerivationPath
83
+ resolveDerivationPathForPurpose(derivationPath: DerivationPath, purpose: SeedPurpose): DerivationPath
72
84
  }
73
85
 
74
86
  interface SignMessagesAPI {
@@ -81,11 +93,16 @@ interface SignTransactionsAPI {
81
93
  signTransactions(authToken: AuthToken, signingRequests: SigningRequest[]): SigningResult[]
82
94
  }
83
95
 
96
+ interface SeedVaultAvailabilityAPI {
97
+ isSeedVaultAvailable(allowSimulated: boolean): boolean
98
+ }
99
+
84
100
  export interface SeedVaultAPI
85
101
  extends AuthorizeSeedAPI,
86
102
  AccountAPI,
87
103
  CreateNewSeedAPI,
88
104
  ImportExistingSeedAPI,
89
105
  PublicKeyAPI,
106
+ SeedVaultAvailabilityAPI,
90
107
  SignMessagesAPI,
91
- SignTransactionsAPI {}
108
+ SignTransactionsAPI {}