@solana-mobile/seed-vault-lib 0.2.1 → 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,8 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
43
44
  init {
44
45
  reactContext.addActivityEventListener(mActivityEventListener)
45
46
 
46
- if (SeedVault.isAvailable(reactContext, true)) {
47
+ if (reactContext.checkSelfPermission(WalletContractV1.PERMISSION_ACCESS_SEED_VAULT) == PackageManager.PERMISSION_GRANTED &&
48
+ SeedVault.isAvailable(reactContext, true)) {
47
49
  observeSeedVaultContentChanges()
48
50
  }
49
51
  }
@@ -64,9 +66,17 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
64
66
 
65
67
  @ReactMethod
66
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) {
67
78
  val application = reactContext.currentActivity?.application!!
68
- val hasUnauthorizedSeeds = Wallet.hasUnauthorizedSeedsForPurpose(application,
69
- WalletContractV1.PURPOSE_SIGN_SOLANA_TRANSACTION)
79
+ val hasUnauthorizedSeeds = Wallet.hasUnauthorizedSeedsForPurpose(application, purpose)
70
80
  promise.resolve(hasUnauthorizedSeeds)
71
81
  }
72
82
 
@@ -110,11 +120,10 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
110
120
  }
111
121
 
112
122
  @ReactMethod
113
- fun getAccounts(authToken: String, promise: Promise) {
123
+ fun getAccounts(authToken: String, filterOnColumn: String, value: Any, promise: Promise) {
114
124
  val application = reactContext.currentActivity?.application!!
115
125
  val accountsCursor = Wallet.getAccounts(application, authToken.toLong(),
116
- WalletContractV1.ACCOUNTS_ALL_COLUMNS,
117
- WalletContractV1.ACCOUNTS_ACCOUNT_IS_USER_WALLET, "1")!!
126
+ WalletContractV1.ACCOUNTS_ALL_COLUMNS, filterOnColumn, value)!!
118
127
 
119
128
  val accounts = mutableListOf<Account>()
120
129
 
@@ -134,6 +143,11 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
134
143
  promise.resolve(accounts.toWritableArray())
135
144
  }
136
145
 
146
+ @ReactMethod
147
+ fun getUserWallets(authToken: String, promise: Promise) {
148
+ getAccounts(authToken, WalletContractV1.ACCOUNTS_ACCOUNT_IS_USER_WALLET, "1", promise)
149
+ }
150
+
137
151
  @ReactMethod
138
152
  fun requestAuthorizeNewSeed() {
139
153
  Log.d(TAG, "Requesting authorization for a new seed...")
@@ -230,6 +244,16 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
230
244
  Log.d(TAG, "Account name updated (to '$name')")
231
245
  }
232
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
+
233
257
  @ReactMethod
234
258
  fun requestSignMessage(authToken: String, derivationPath: String, message: ReadableArray) {
235
259
  requestSignMessages(authToken, listOf(SigningRequest(message.toByteArray(), arrayListOf(Uri.parse(derivationPath)))))
@@ -421,7 +445,7 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
421
445
  Arguments.createMap().apply {
422
446
  putArray("publicKey", response.publicKey.toWritableArray())
423
447
  putString("publicKeyEncoded", response.publicKeyEncoded)
424
- putString("resolvedDerviationPath", response.resolvedDerivationPath.toString())
448
+ putString("resolvedDerivationPath", response.resolvedDerivationPath.toString())
425
449
  }
426
450
  }), null
427
451
  )
@@ -432,6 +456,21 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
432
456
  }
433
457
  }
434
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
+
435
474
  private fun sendEvent(reactContext: ReactContext, eventName: String, params: WritableMap? = null) {
436
475
  reactContext
437
476
  .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
@@ -455,7 +494,6 @@ class SolanaMobileSeedVaultLibModule(val reactContext: ReactApplicationContext)
455
494
  throw NotImplementedError("Stub for legacy onChange")
456
495
 
457
496
  override fun onChange(selfChange: Boolean, uris: Collection<Uri>, flags: Int) {
458
- Log.d(TAG, "Received change notification for $uris (flags=$flags); refreshing viewmodel")
459
497
  sendEvent(reactContext, SEED_VAULT_CONTENT_CHANGE_EVENT_BRIDGE_NAME,
460
498
  params = Arguments.createMap().apply {
461
499
  putString("__type", "SeedVaultContentChange")
@@ -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;
@@ -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;
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.1",
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 {