@getpara/react-native-wallet 2.0.0-dev.1 → 2.0.0-dev.2

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.
@@ -1,10 +1,7 @@
1
1
  import { StorageUtils } from '@getpara/web-sdk';
2
- /**
3
- * Implements `StorageUtils` using React Native Async Storage.
4
- */
5
2
  export declare class AsyncStorage implements StorageUtils {
6
- clear(prefix: string): Promise<void>;
7
3
  get(key: string): Promise<string | null>;
8
- removeItem(key: string): Promise<void>;
9
4
  set(key: string, value: string): Promise<void>;
5
+ removeItem(key: string): Promise<void>;
6
+ clear(prefix: string): Promise<void>;
10
7
  }
@@ -8,33 +8,56 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import RNAsyncStorage from '@react-native-async-storage/async-storage';
11
- /**
12
- * Implements `StorageUtils` using React Native Async Storage.
13
- */
14
11
  export class AsyncStorage {
15
- clear(prefix) {
12
+ get(key) {
16
13
  return __awaiter(this, void 0, void 0, function* () {
17
- const keys = yield RNAsyncStorage.getAllKeys();
18
- for (const key of keys) {
19
- if (key.startsWith(prefix)) {
20
- yield RNAsyncStorage.removeItem(key);
21
- }
14
+ try {
15
+ return yield RNAsyncStorage.getItem(key);
16
+ }
17
+ catch (error) {
18
+ console.warn('Error retrieving stored item:', error);
19
+ return null;
22
20
  }
23
21
  });
24
22
  }
25
- get(key) {
23
+ set(key, value) {
26
24
  return __awaiter(this, void 0, void 0, function* () {
27
- return RNAsyncStorage.getItem(key);
25
+ try {
26
+ yield RNAsyncStorage.setItem(key, value);
27
+ }
28
+ catch (error) {
29
+ console.warn(`Error storing key ${key}:`, error);
30
+ }
28
31
  });
29
32
  }
30
33
  removeItem(key) {
31
34
  return __awaiter(this, void 0, void 0, function* () {
32
- yield RNAsyncStorage.removeItem(key);
35
+ try {
36
+ yield RNAsyncStorage.removeItem(key);
37
+ }
38
+ catch (error) {
39
+ console.warn(`Error removing key ${key}:`, error);
40
+ }
33
41
  });
34
42
  }
35
- set(key, value) {
43
+ clear(prefix) {
36
44
  return __awaiter(this, void 0, void 0, function* () {
37
- yield RNAsyncStorage.setItem(key, value);
45
+ try {
46
+ const keys = yield RNAsyncStorage.getAllKeys();
47
+ for (const key of keys) {
48
+ if (key.startsWith(prefix)) {
49
+ try {
50
+ yield RNAsyncStorage.removeItem(key);
51
+ }
52
+ catch (error) {
53
+ console.warn(`Error clearing key ${key}:`, error);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ catch (error) {
59
+ console.warn(`Error getting keys for prefix ${prefix}:`, error);
60
+ }
38
61
  });
39
62
  }
40
63
  }
@@ -1,7 +1,4 @@
1
1
  import { StorageUtils } from '@getpara/web-sdk';
2
- /**
3
- * Implements `StorageUtils` using React Native `Keychain`.
4
- */
5
2
  export declare class KeychainStorage implements StorageUtils {
6
3
  get(key: string): Promise<string | null>;
7
4
  set(key: string, value: string): Promise<void>;
@@ -9,17 +9,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import Keychain from 'react-native-keychain';
11
11
  const USERNAME = '@CAPSULE';
12
- const KEYCHAIN_USER_CANCELLED_ERRORS = [
13
- 'user canceled the operation',
14
- 'error: code: 13, msg: cancel',
15
- 'error: code: 10, msg: fingerprint operation canceled by the user',
16
- ];
17
- function isUserCancelledError(error) {
18
- return KEYCHAIN_USER_CANCELLED_ERRORS.some(userCancelledError => error.toString().toLowerCase().includes(userCancelledError));
19
- }
20
- /**
21
- * Implements `StorageUtils` using React Native `Keychain`.
22
- */
23
12
  export class KeychainStorage {
24
13
  get(key) {
25
14
  return __awaiter(this, void 0, void 0, function* () {
@@ -33,39 +22,57 @@ export class KeychainStorage {
33
22
  return item.password;
34
23
  }
35
24
  catch (error) {
36
- if (error instanceof Error && !isUserCancelledError(error)) {
37
- // triggered when biometry verification fails and user cancels the action
38
- throw new Error('Error retrieving stored item ' + error.message);
39
- }
40
- throw error;
25
+ console.warn('Error retrieving stored item:', error);
26
+ return null;
41
27
  }
42
28
  });
43
29
  }
44
30
  set(key, value) {
45
31
  return __awaiter(this, void 0, void 0, function* () {
46
- const result = yield Keychain.setGenericPassword(USERNAME, value, {
47
- service: key,
48
- accessible: Keychain.ACCESSIBLE.AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY,
49
- securityLevel: Keychain.SECURITY_LEVEL.ANY,
50
- });
51
- if (!result) {
52
- throw new Error('Failed to store key ' + key);
32
+ try {
33
+ const result = yield Keychain.setGenericPassword(USERNAME, value, {
34
+ service: key,
35
+ accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED,
36
+ securityLevel: Keychain.SECURITY_LEVEL.ANY,
37
+ storage: Keychain.STORAGE_TYPE.AES_GCM_NO_AUTH,
38
+ });
39
+ if (!result) {
40
+ console.warn(`Failed to store key ${key}`);
41
+ }
42
+ }
43
+ catch (error) {
44
+ console.warn(`Error storing key ${key}:`, error);
53
45
  }
54
46
  });
55
47
  }
56
48
  removeItem(key) {
57
49
  return __awaiter(this, void 0, void 0, function* () {
58
- yield Keychain.resetGenericPassword({ service: key });
50
+ try {
51
+ yield Keychain.resetGenericPassword({ service: key });
52
+ }
53
+ catch (error) {
54
+ console.warn(`Error removing key ${key}:`, error);
55
+ }
59
56
  });
60
57
  }
61
58
  clear(prefix) {
62
59
  return __awaiter(this, void 0, void 0, function* () {
63
- const services = yield Keychain.getAllGenericPasswordServices();
64
- for (const key of services) {
65
- if (key && key.startsWith(prefix)) {
66
- yield Keychain.resetGenericPassword({ service: key });
60
+ try {
61
+ const services = yield Keychain.getAllGenericPasswordServices();
62
+ for (const key of services) {
63
+ if (key && key.startsWith(prefix)) {
64
+ try {
65
+ yield Keychain.resetGenericPassword({ service: key });
66
+ }
67
+ catch (error) {
68
+ console.warn(`Error clearing key ${key}:`, error);
69
+ }
70
+ }
67
71
  }
68
72
  }
73
+ catch (error) {
74
+ console.warn(`Error getting services for prefix ${prefix}:`, error);
75
+ }
69
76
  });
70
77
  }
71
78
  }
package/dist/config.d.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  import { Environment } from '@getpara/web-sdk';
2
+ declare function getPortalBaseURL(env: Environment): "http://localhost:3003" | "https://app.sandbox.usecapsule.com" | "https://app.beta.usecapsule.com" | "https://app.usecapsule.com";
3
+ declare function getBaseUrl(env: Environment): string;
2
4
  export declare function getBaseMPCNetworkWSUrl(env: Environment): string;
3
5
  export declare let userManagementServer: string;
4
6
  export declare let portalBase: string;
5
7
  export declare let mpcNetworkWSServer: string;
6
8
  export declare function setEnv(env: Environment): void;
7
9
  export declare const DEBUG_MODE_ENABLED = false;
10
+ export { getBaseUrl, getPortalBaseURL };
package/dist/config.js CHANGED
@@ -58,3 +58,4 @@ function init() {
58
58
  ParaSignerModule.setWsServerUrl(mpcNetworkWSServer);
59
59
  }
60
60
  init();
61
+ export { getBaseUrl, getPortalBaseURL };
@@ -1,5 +1,4 @@
1
- import { ConstructorOpts, ParaCore, Environment, PlatformUtils } from '@getpara/web-sdk';
2
- import { Auth } from '@getpara/user-management-client';
1
+ import { AuthStateSignup, ConstructorOpts, ParaCore, Environment, PlatformUtils } from '@getpara/web-sdk';
3
2
  /**
4
3
  * Represents a mobile implementation of the Para SDK.
5
4
  * @extends ParaCore
@@ -8,6 +7,7 @@ import { Auth } from '@getpara/user-management-client';
8
7
  * const para = new ParaMobile(Environment.BETA, "api_key");
9
8
  */
10
9
  export declare class ParaMobile extends ParaCore {
10
+ isNativePasskey: boolean;
11
11
  private relyingPartyId;
12
12
  /**
13
13
  * Creates an instance of ParaMobile.
@@ -17,36 +17,20 @@ export declare class ParaMobile extends ParaCore {
17
17
  * @param {ConstructorOpts} [opts] - Additional constructor options.
18
18
  */
19
19
  constructor(env: Environment, apiKey: string, relyingPartyId?: string, opts?: ConstructorOpts);
20
+ protected ready(): Promise<void>;
20
21
  protected getPlatformUtils(): PlatformUtils;
21
- /**
22
- * Verifies an email and returns the biometrics ID.
23
- * @param {string} verificationCode - The verification code sent to the email.
24
- * @returns {Promise<string>} The biometrics ID.
25
- */
26
- verifyEmailBiometricsId({ verificationCode }: {
27
- verificationCode: string;
28
- }): Promise<string>;
29
- /**
30
- * Verifies a phone number and returns the biometrics ID.
31
- * @param {string} verificationCode - The verification code sent to the phone.
32
- * @returns {Promise<string>} The biometrics ID.
33
- */
34
- verifyPhoneBiometricsId({ verificationCode }: {
35
- verificationCode: string;
36
- }): Promise<string>;
22
+ isPasskeySupported(): Promise<boolean>;
37
23
  /**
38
24
  * Registers a passkey for the user.
39
25
  * @param {Auth<'email'> | Auth<'phone'>} auth - The user's authentication details
40
26
  * @param {string} biometricsId - The biometrics ID obtained from verification.
41
27
  * @returns {Promise<void>}
42
28
  */
43
- registerPasskey({ biometricsId, ...auth }: {
44
- biometricsId: string;
45
- } & (Auth<'email'> | Auth<'phone'>)): Promise<void>;
29
+ registerPasskey(authState: AuthStateSignup): Promise<void>;
46
30
  /**
47
31
  * Logs in the user using their authentication credentials.
48
32
  * @param {AuthParams} params - The authentication parameters.
49
33
  * @returns {Promise<void>}
50
34
  */
51
- login({ ...auth }: Auth<'email'> | Auth<'phone'>): Promise<void>;
35
+ loginWithPasskey(): Promise<void>;
52
36
  }
@@ -7,22 +7,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- var __rest = (this && this.__rest) || function (s, e) {
11
- var t = {};
12
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
13
- t[p] = s[p];
14
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
15
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
16
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
17
- t[p[i]] = s[p[i]];
18
- }
19
- return t;
20
- };
21
10
  import { ParaCore, Environment, decryptPrivateKeyAndDecryptShare, encryptPrivateKey, getAsymmetricKeyPair, getDerivedPrivateKeyAndDecrypt, getPublicKeyHex, getSHA256HashHex, parseCredentialCreationRes, } from '@getpara/web-sdk';
22
- import * as Sentry from '@sentry/react-native';
23
11
  import { ReactNativeUtils } from './ReactNativeUtils.js';
24
12
  import { Passkey, } from 'react-native-passkey';
25
- import { extractAuthInfo, PublicKeyStatus } from '@getpara/user-management-client';
13
+ import { PublicKeyStatus } from '@getpara/user-management-client';
26
14
  import { setEnv } from '../config.js';
27
15
  import base64url from 'base64url';
28
16
  import { webcrypto } from 'crypto';
@@ -45,14 +33,7 @@ export class ParaMobile extends ParaCore {
45
33
  */
46
34
  constructor(env, apiKey, relyingPartyId, opts) {
47
35
  super(env, apiKey, opts);
48
- // starting with non-prod to see what kind of errors we get and if sensitive data is tracked
49
- // will turn on in prod after monitoring
50
- if (env !== Environment.PROD && env !== Environment.DEV) {
51
- Sentry.init({
52
- environment: env.toLowerCase(),
53
- dsn: 'https://59cea0cfbbb30a646c4e9f2feea06da4@o4504568036720640.ingest.us.sentry.io/4508850922323968',
54
- });
55
- }
36
+ this.isNativePasskey = true;
56
37
  setEnv(env);
57
38
  if (relyingPartyId) {
58
39
  this.relyingPartyId = relyingPartyId;
@@ -73,41 +54,17 @@ export class ParaMobile extends ParaCore {
73
54
  }
74
55
  }
75
56
  }
57
+ ready() {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ this.isReady = true;
60
+ });
61
+ }
76
62
  getPlatformUtils() {
77
63
  return new ReactNativeUtils();
78
64
  }
79
- /**
80
- * Verifies an email and returns the biometrics ID.
81
- * @param {string} verificationCode - The verification code sent to the email.
82
- * @returns {Promise<string>} The biometrics ID.
83
- */
84
- verifyEmailBiometricsId(_a) {
85
- const _super = Object.create(null, {
86
- verifyEmail: { get: () => super.verifyEmail }
87
- });
88
- return __awaiter(this, arguments, void 0, function* ({ verificationCode }) {
89
- const webAuthCreateUrl = yield _super.verifyEmail.call(this, { verificationCode });
90
- const segments = webAuthCreateUrl.split('/');
91
- const segments2 = segments[segments.length - 1].split('?');
92
- const biometricsId = segments2[0];
93
- return biometricsId;
94
- });
95
- }
96
- /**
97
- * Verifies a phone number and returns the biometrics ID.
98
- * @param {string} verificationCode - The verification code sent to the phone.
99
- * @returns {Promise<string>} The biometrics ID.
100
- */
101
- verifyPhoneBiometricsId(_a) {
102
- const _super = Object.create(null, {
103
- verifyPhone: { get: () => super.verifyPhone }
104
- });
105
- return __awaiter(this, arguments, void 0, function* ({ verificationCode }) {
106
- const webAuthCreateUrl = yield _super.verifyPhone.call(this, { verificationCode });
107
- const segments = webAuthCreateUrl.split('/');
108
- const segments2 = segments[segments.length - 1].split('?');
109
- const biometricsId = segments2[0];
110
- return biometricsId;
65
+ isPasskeySupported() {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ return Passkey.isSupported();
111
68
  });
112
69
  }
113
70
  /**
@@ -116,16 +73,19 @@ export class ParaMobile extends ParaCore {
116
73
  * @param {string} biometricsId - The biometrics ID obtained from verification.
117
74
  * @returns {Promise<void>}
118
75
  */
119
- registerPasskey(_a) {
76
+ registerPasskey(authState) {
120
77
  return __awaiter(this, void 0, void 0, function* () {
121
- var { biometricsId } = _a, auth = __rest(_a, ["biometricsId"]);
78
+ if (!authState.passkeyId) {
79
+ throw new Error('Passkey ID not found. Make sure you have enabled passkey logins in the Para Developer Portal.');
80
+ }
81
+ const userId = this.assertUserId();
82
+ const authInfo = this.assertIsAuthSet();
122
83
  if (!webcrypto || !webcrypto.getRandomValues) {
123
84
  throw new Error('Web crypto is not available. Ensure you have imported the shim from @getpara/react-native-wallet.');
124
85
  }
125
86
  const userHandle = new Uint8Array(32);
126
87
  webcrypto.getRandomValues(userHandle);
127
88
  const userHandleEncoded = base64url.encode(userHandle);
128
- const { identifier: displayIdentifier } = extractAuthInfo(auth, { isRequired: true });
129
89
  const requestJson = {
130
90
  authenticatorSelection: {
131
91
  authenticatorAttachment: 'platform',
@@ -139,8 +99,8 @@ export class ParaMobile extends ParaCore {
139
99
  },
140
100
  user: {
141
101
  id: userHandleEncoded,
142
- name: displayIdentifier,
143
- displayName: displayIdentifier,
102
+ name: authInfo.identifier,
103
+ displayName: authInfo.identifier,
144
104
  },
145
105
  pubKeyCredParams: [
146
106
  {
@@ -170,14 +130,14 @@ export class ParaMobile extends ParaCore {
170
130
  const encryptionKeyHash = getSHA256HashHex(userHandleEncoded);
171
131
  const encryptedPrivateKeyHex = yield encryptPrivateKey(keyPair, userHandleEncoded);
172
132
  const { partnerId } = yield this.ctx.client.touchSession();
173
- yield this.ctx.client.patchSessionPublicKey(partnerId, this.getUserId(), biometricsId, {
133
+ yield this.ctx.client.patchSessionPublicKey(partnerId, userId, authState.passkeyId, {
174
134
  publicKey: resultJson.id,
175
135
  sigDerivedPublicKey: publicKeyHex,
176
136
  cosePublicKey,
177
137
  clientDataJSON,
178
138
  status: PublicKeyStatus.COMPLETE,
179
139
  });
180
- yield this.ctx.client.uploadEncryptedWalletPrivateKey(this.getUserId(), encryptedPrivateKeyHex, encryptionKeyHash, resultJson.id);
140
+ yield this.ctx.client.uploadEncryptedWalletPrivateKey(userId, encryptedPrivateKeyHex, encryptionKeyHash, resultJson.id);
181
141
  });
182
142
  }
183
143
  /**
@@ -185,12 +145,11 @@ export class ParaMobile extends ParaCore {
185
145
  * @param {AuthParams} params - The authentication parameters.
186
146
  * @returns {Promise<void>}
187
147
  */
188
- login(_a) {
148
+ loginWithPasskey() {
189
149
  return __awaiter(this, void 0, void 0, function* () {
190
- var auth = __rest(_a, []);
191
- yield this.logout();
192
- const authInfo = extractAuthInfo(auth, { isRequired: true });
193
- const { challenge, allowedPublicKeys } = yield this.ctx.client.getWebChallenge(authInfo.auth);
150
+ this.assertIsAuthSet();
151
+ const userId = this.assertUserId();
152
+ const { challenge, allowedPublicKeys } = yield this.ctx.client.getWebChallenge({ userId });
194
153
  const requestJson = {
195
154
  challenge,
196
155
  timeout: 60000,
@@ -205,7 +164,7 @@ export class ParaMobile extends ParaCore {
205
164
  else {
206
165
  resultJson = result;
207
166
  }
208
- const { partnerId } = yield this.ctx.client.touchSession();
167
+ const { partnerId, sessionLookupId } = yield this.ctx.client.touchSession();
209
168
  const publicKey = resultJson.id;
210
169
  const verifyWebChallengeResult = yield this.ctx.client.verifyWebChallenge(partnerId, {
211
170
  publicKey,
@@ -215,17 +174,8 @@ export class ParaMobile extends ParaCore {
215
174
  signature: resultJson.response.signature,
216
175
  },
217
176
  });
218
- const userId = verifyWebChallengeResult.data.userId;
219
- yield this.setUserId(userId);
220
- const { user } = yield this.ctx.client.getUser(userId);
221
- if (user.phone) {
222
- yield this.setPhoneNumber(user.phone.number, user.phone.countryCode);
223
- }
224
- if (user.email) {
225
- yield this.setEmail(user.email);
226
- }
227
- if (user.farcasterUsername) {
228
- yield this.setFarcasterUsername(user.farcasterUsername);
177
+ if (userId !== verifyWebChallengeResult.data.userId) {
178
+ throw new Error('User ID mismatch');
229
179
  }
230
180
  const encryptedSharesResult = yield this.ctx.client.getBiometricKeyshares(userId, resultJson.id);
231
181
  const encryptionKeyHash = getSHA256HashHex(resultJson.response.userHandle);
@@ -254,7 +204,16 @@ export class ParaMobile extends ParaCore {
254
204
  type: desiredWallet.type || undefined,
255
205
  };
256
206
  }
207
+ const currentWalletIds = {};
208
+ for (const wallet of Object.values(walletsToInsert)) {
209
+ const { id, type } = wallet;
210
+ const currentIdsForType = currentWalletIds[type || 'EVM'] || [];
211
+ currentWalletIds[type || 'EVM'] = [...currentIdsForType, id];
212
+ }
257
213
  yield this.setWallets(walletsToInsert);
214
+ yield this.setCurrentWalletIds(currentWalletIds, {
215
+ sessionLookupId,
216
+ });
258
217
  });
259
218
  }
260
219
  }
@@ -1,10 +1,11 @@
1
1
  import { PlatformUtils, TPregenIdentifierType } from '@getpara/web-sdk';
2
2
  import { Ctx } from '@getpara/web-sdk';
3
3
  import { SignatureRes } from '@getpara/web-sdk';
4
- import { BackupKitEmailProps, WalletType } from '@getpara/user-management-client';
4
+ import { BackupKitEmailProps, TWalletType, SDKType } from '@getpara/user-management-client';
5
5
  import { AsyncStorage } from '../AsyncStorage.js';
6
6
  import { KeychainStorage } from '../KeychainStorage.js';
7
7
  export declare class ReactNativeUtils implements PlatformUtils {
8
+ sdkType: SDKType;
8
9
  disableProviderModal?: boolean | undefined;
9
10
  localStorage: AsyncStorage;
10
11
  sessionStorage: AsyncStorage;
@@ -14,7 +15,7 @@ export declare class ReactNativeUtils implements PlatformUtils {
14
15
  p: string;
15
16
  q: string;
16
17
  }>;
17
- keygen(ctx: Ctx, userId: string, type: Exclude<WalletType, WalletType.SOLANA>, _secretKey: string | null, _sessionCookie: string, _emailProps?: BackupKitEmailProps | undefined): Promise<{
18
+ keygen(ctx: Ctx, userId: string, type: Exclude<TWalletType, 'SOLANA'>, _secretKey: string | null, _sessionCookie: string, _emailProps?: BackupKitEmailProps | undefined): Promise<{
18
19
  signer: string;
19
20
  walletId: string;
20
21
  }>;
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { KeyShareType, WalletScheme, WalletType } from '@getpara/user-management-client';
10
+ import { KeyShareType } from '@getpara/user-management-client';
11
11
  import { NativeModules } from 'react-native';
12
12
  import { AsyncStorage } from '../AsyncStorage.js';
13
13
  import { KeychainStorage } from '../KeychainStorage.js';
@@ -47,6 +47,7 @@ function sendTransactionRequest(ctx, userId, walletId, protocolId, transaction,
47
47
  }
48
48
  export class ReactNativeUtils {
49
49
  constructor() {
50
+ this.sdkType = 'REACT_NATIVE';
50
51
  this.localStorage = new AsyncStorage();
51
52
  this.sessionStorage = new AsyncStorage();
52
53
  this.secureStorage = new KeychainStorage();
@@ -63,7 +64,7 @@ export class ReactNativeUtils {
63
64
  const { walletId, protocolId } = yield ctx.client.createWallet(userId, {
64
65
  type,
65
66
  useTwoSigners: true,
66
- scheme: ctx.useDKLS ? WalletScheme.DKLS : WalletScheme.CGGMP,
67
+ scheme: ctx.useDKLS ? 'DKLS' : 'CGGMP',
67
68
  });
68
69
  if (ctx.mpcComputationClient && !ctx.useDKLS) {
69
70
  const { signer } = yield keygenRequest(ctx, userId, walletId, protocolId);
@@ -141,8 +142,8 @@ export class ReactNativeUtils {
141
142
  ed25519Keygen(ctx, userId, _sessionCookie, _emailProps) {
142
143
  return __awaiter(this, void 0, void 0, function* () {
143
144
  const { walletId, protocolId } = yield ctx.client.createWallet(userId, {
144
- scheme: WalletScheme.ED25519,
145
- type: WalletType.SOLANA,
145
+ scheme: 'ED25519',
146
+ type: 'SOLANA',
146
147
  });
147
148
  const signer = yield ParaSignerModule.ed25519CreateAccount(walletId, protocolId);
148
149
  return { signer, walletId };
@@ -153,8 +154,8 @@ export class ReactNativeUtils {
153
154
  const { walletId, protocolId } = yield ctx.client.createPregenWallet({
154
155
  pregenIdentifier,
155
156
  pregenIdentifierType,
156
- scheme: WalletScheme.ED25519,
157
- type: WalletType.SOLANA,
157
+ scheme: 'ED25519',
158
+ type: 'SOLANA',
158
159
  });
159
160
  const signer = yield ParaSignerModule.ed25519CreateAccount(walletId, protocolId);
160
161
  return { signer, walletId };
@@ -162,7 +163,7 @@ export class ReactNativeUtils {
162
163
  }
163
164
  ed25519Sign(ctx, userId, walletId, share, base64Bytes, _sessionCookie) {
164
165
  return __awaiter(this, void 0, void 0, function* () {
165
- const { protocolId } = yield ctx.client.preSignMessage(userId, walletId, base64Bytes, WalletScheme.ED25519);
166
+ const { protocolId } = yield ctx.client.preSignMessage(userId, walletId, base64Bytes, 'ED25519');
166
167
  const base64Sig = yield ParaSignerModule.ed25519Sign(protocolId, share, base64Bytes);
167
168
  return { signature: base64Sig };
168
169
  });
package/dist/shim.js CHANGED
@@ -8,6 +8,7 @@ import { Buffer } from '@craftzdog/react-native-buffer';
8
8
  import process from 'process';
9
9
  import 'react-native-url-polyfill/auto';
10
10
  import { TextEncoder, TextDecoder } from 'text-encoding';
11
+ import structuredClone from '@ungap/structured-clone';
11
12
  const setupProcessPolyfill = () => {
12
13
  if (typeof globalThis.process === 'undefined') {
13
14
  globalThis.process = process;
@@ -61,8 +62,14 @@ const setupTextEncodingPolyfills = () => {
61
62
  globalThis.TextEncoder = TextEncoder;
62
63
  globalThis.TextDecoder = TextDecoder;
63
64
  };
65
+ const setupStructuredClonePolyfill = () => {
66
+ if (typeof globalThis.structuredClone === 'undefined') {
67
+ globalThis.structuredClone = structuredClone;
68
+ }
69
+ };
64
70
  setupProcessPolyfill();
65
71
  setupBufferPolyfill();
66
72
  setupBase64Polyfills();
67
73
  setupCryptoPolyfills();
68
74
  setupTextEncodingPolyfills();
75
+ setupStructuredClonePolyfill();
package/package.json CHANGED
@@ -1,50 +1,56 @@
1
1
  {
2
2
  "name": "@getpara/react-native-wallet",
3
- "version": "2.0.0-dev.1",
4
3
  "description": "Para Wallet for React Native",
5
- "homepage": "https://getpara.com",
4
+ "version": "2.0.0-dev.2",
6
5
  "author": "Para Team <hello@getpara.com> (https://getpara.com)",
7
- "main": "dist/index.js",
8
- "module": "dist/index.js",
9
- "types": "dist/index.d.ts",
10
- "files": [
11
- "dist",
12
- "src",
13
- "ios",
14
- "android",
15
- "cpp",
16
- "*.podspec",
17
- "signer.xcframework",
18
- "signer.aar"
19
- ],
20
- "scripts": {
21
- "build": "rm -rf dist && tsc",
22
- "compile-signer": "bash ./scripts/compileSigner.sh"
23
- },
24
6
  "dependencies": {
25
- "@getpara/core-sdk": "2.0.0-dev.1",
26
- "@getpara/user-management-client": "2.0.0-dev.1",
27
- "@getpara/web-sdk": "2.0.0-dev.1",
7
+ "@getpara/core-sdk": "2.0.0-dev.2",
8
+ "@getpara/user-management-client": "2.0.0-dev.2",
9
+ "@getpara/web-sdk": "2.0.0-dev.2",
28
10
  "@peculiar/webcrypto": "^1.5.0",
29
- "@sentry/react-native": "^6.7.0",
11
+ "@ungap/structured-clone": "1.3.0",
30
12
  "node-forge": "1.3.1",
31
13
  "react-native-url-polyfill": "2.0.0",
32
14
  "text-encoding": "0.7.0"
33
15
  },
34
16
  "devDependencies": {
35
17
  "@craftzdog/react-native-buffer": "6.0.5",
36
- "@react-native-async-storage/async-storage": "2.1.0",
18
+ "@react-native-async-storage/async-storage": "2.1.2",
37
19
  "@types/node-forge": "1.3.1",
38
20
  "@types/react": "^18.0.31",
39
21
  "@types/react-native": "0.70.0",
40
22
  "@types/text-encoding": "0.0.39",
41
- "react-native-keychain": "9.2.2",
23
+ "react-native-keychain": "10.0.0",
42
24
  "react-native-modpow": "1.1.0",
43
- "react-native-passkey": "3.0.0",
25
+ "react-native-passkey": "3.1.0",
44
26
  "react-native-quick-base64": "2.1.2",
45
- "react-native-quick-crypto": "0.7.11",
46
- "typescript": "^5.4.3"
27
+ "react-native-quick-crypto": "0.7.12",
28
+ "typescript": "^5.8.3"
47
29
  },
30
+ "exports": {
31
+ ".": {
32
+ "default": "./dist/index.js"
33
+ },
34
+ "./shim": {
35
+ "default": "./dist/shim.js"
36
+ },
37
+ "./dist/shim.js": {
38
+ "default": "./dist/shim.js"
39
+ }
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "src",
44
+ "ios",
45
+ "android",
46
+ "cpp",
47
+ "*.podspec",
48
+ "signer.xcframework",
49
+ "signer.aar"
50
+ ],
51
+ "homepage": "https://getpara.com",
52
+ "main": "./dist/index.js",
53
+ "module": "./dist/index.js",
48
54
  "peerDependencies": {
49
55
  "@craftzdog/react-native-buffer": "*",
50
56
  "@react-native-async-storage/async-storage": "*",
@@ -60,5 +66,32 @@
60
66
  "publishConfig": {
61
67
  "access": "public"
62
68
  },
63
- "gitHead": "426e843bd6084fb2e5f30ab87b02c79fc2f52832"
69
+ "react-native": {
70
+ ".": "./dist/index.js",
71
+ "./shim": "./dist/shim.js",
72
+ "./dist/shim.js": "./dist/shim.js"
73
+ },
74
+ "scripts": {
75
+ "build": "rm -rf dist && tsc",
76
+ "compile-signer": "bash ./scripts/compileSigner.sh",
77
+ "test": "vitest run --coverage"
78
+ },
79
+ "sideEffects": [
80
+ "./dist/shim.js"
81
+ ],
82
+ "types": "./dist/index.d.ts",
83
+ "typesVersions": {
84
+ "*": {
85
+ "shim": [
86
+ "./dist/shim.d.ts"
87
+ ],
88
+ "dist/shim.js": [
89
+ "./dist/shim.d.ts"
90
+ ],
91
+ "*": [
92
+ "./dist/index.d.ts"
93
+ ]
94
+ }
95
+ },
96
+ "gitHead": "77d818539daa181c839a40f0ad5362af4058844e"
64
97
  }
@@ -1,28 +1,46 @@
1
1
  import { StorageUtils } from '@getpara/web-sdk';
2
2
  import RNAsyncStorage from '@react-native-async-storage/async-storage';
3
3
 
4
- /**
5
- * Implements `StorageUtils` using React Native Async Storage.
6
- */
7
4
  export class AsyncStorage implements StorageUtils {
8
- async clear(prefix: string): Promise<void> {
9
- const keys = await RNAsyncStorage.getAllKeys();
10
- for (const key of keys) {
11
- if (key.startsWith(prefix)) {
12
- await RNAsyncStorage.removeItem(key);
13
- }
5
+ async get(key: string): Promise<string | null> {
6
+ try {
7
+ return await RNAsyncStorage.getItem(key);
8
+ } catch (error) {
9
+ console.warn('Error retrieving stored item:', error);
10
+ return null;
14
11
  }
15
12
  }
16
13
 
17
- async get(key: string): Promise<string | null> {
18
- return RNAsyncStorage.getItem(key);
14
+ async set(key: string, value: string): Promise<void> {
15
+ try {
16
+ await RNAsyncStorage.setItem(key, value);
17
+ } catch (error) {
18
+ console.warn(`Error storing key ${key}:`, error);
19
+ }
19
20
  }
20
21
 
21
22
  async removeItem(key: string): Promise<void> {
22
- await RNAsyncStorage.removeItem(key);
23
+ try {
24
+ await RNAsyncStorage.removeItem(key);
25
+ } catch (error) {
26
+ console.warn(`Error removing key ${key}:`, error);
27
+ }
23
28
  }
24
29
 
25
- async set(key: string, value: string): Promise<void> {
26
- await RNAsyncStorage.setItem(key, value);
30
+ async clear(prefix: string): Promise<void> {
31
+ try {
32
+ const keys = await RNAsyncStorage.getAllKeys();
33
+ for (const key of keys) {
34
+ if (key.startsWith(prefix)) {
35
+ try {
36
+ await RNAsyncStorage.removeItem(key);
37
+ } catch (error) {
38
+ console.warn(`Error clearing key ${key}:`, error);
39
+ }
40
+ }
41
+ }
42
+ } catch (error) {
43
+ console.warn(`Error getting keys for prefix ${prefix}:`, error);
44
+ }
27
45
  }
28
46
  }
@@ -2,21 +2,7 @@ import { StorageUtils } from '@getpara/web-sdk';
2
2
  import Keychain from 'react-native-keychain';
3
3
 
4
4
  const USERNAME = '@CAPSULE';
5
- const KEYCHAIN_USER_CANCELLED_ERRORS = [
6
- 'user canceled the operation',
7
- 'error: code: 13, msg: cancel',
8
- 'error: code: 10, msg: fingerprint operation canceled by the user',
9
- ];
10
5
 
11
- function isUserCancelledError(error: Error) {
12
- return KEYCHAIN_USER_CANCELLED_ERRORS.some(userCancelledError =>
13
- error.toString().toLowerCase().includes(userCancelledError),
14
- );
15
- }
16
-
17
- /**
18
- * Implements `StorageUtils` using React Native `Keychain`.
19
- */
20
6
  export class KeychainStorage implements StorageUtils {
21
7
  async get(key: string): Promise<string | null> {
22
8
  try {
@@ -28,32 +14,49 @@ export class KeychainStorage implements StorageUtils {
28
14
  }
29
15
  return item.password;
30
16
  } catch (error) {
31
- if (error instanceof Error && !isUserCancelledError(error)) {
32
- // triggered when biometry verification fails and user cancels the action
33
- throw new Error('Error retrieving stored item ' + error.message);
34
- }
35
- throw error;
17
+ console.warn('Error retrieving stored item:', error);
18
+ return null;
36
19
  }
37
20
  }
21
+
38
22
  async set(key: string, value: string): Promise<void> {
39
- const result = await Keychain.setGenericPassword(USERNAME, value, {
40
- service: key,
41
- accessible: Keychain.ACCESSIBLE.AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY,
42
- securityLevel: Keychain.SECURITY_LEVEL.ANY,
43
- });
44
- if (!result) {
45
- throw new Error('Failed to store key ' + key);
23
+ try {
24
+ const result = await Keychain.setGenericPassword(USERNAME, value, {
25
+ service: key,
26
+ accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED,
27
+ securityLevel: Keychain.SECURITY_LEVEL.ANY,
28
+ storage: Keychain.STORAGE_TYPE.AES_GCM_NO_AUTH,
29
+ });
30
+ if (!result) {
31
+ console.warn(`Failed to store key ${key}`);
32
+ }
33
+ } catch (error) {
34
+ console.warn(`Error storing key ${key}:`, error);
46
35
  }
47
36
  }
37
+
48
38
  async removeItem(key: string): Promise<void> {
49
- await Keychain.resetGenericPassword({ service: key });
39
+ try {
40
+ await Keychain.resetGenericPassword({ service: key });
41
+ } catch (error) {
42
+ console.warn(`Error removing key ${key}:`, error);
43
+ }
50
44
  }
45
+
51
46
  async clear(prefix: string): Promise<void> {
52
- const services = await Keychain.getAllGenericPasswordServices();
53
- for (const key of services) {
54
- if (key && key.startsWith(prefix)) {
55
- await Keychain.resetGenericPassword({ service: key });
47
+ try {
48
+ const services = await Keychain.getAllGenericPasswordServices();
49
+ for (const key of services) {
50
+ if (key && key.startsWith(prefix)) {
51
+ try {
52
+ await Keychain.resetGenericPassword({ service: key });
53
+ } catch (error) {
54
+ console.warn(`Error clearing key ${key}:`, error);
55
+ }
56
+ }
56
57
  }
58
+ } catch (error) {
59
+ console.warn(`Error getting services for prefix ${prefix}:`, error);
57
60
  }
58
61
  }
59
62
  }
package/src/config.ts CHANGED
@@ -66,3 +66,5 @@ function init() {
66
66
  }
67
67
 
68
68
  init();
69
+
70
+ export { getBaseUrl, getPortalBaseURL };
@@ -1,4 +1,5 @@
1
1
  import {
2
+ AuthStateSignup,
2
3
  ConstructorOpts,
3
4
  ParaCore,
4
5
  Environment,
@@ -12,7 +13,6 @@ import {
12
13
  getSHA256HashHex,
13
14
  parseCredentialCreationRes,
14
15
  } from '@getpara/web-sdk';
15
- import * as Sentry from '@sentry/react-native';
16
16
 
17
17
  import { ReactNativeUtils } from './ReactNativeUtils.js';
18
18
  import {
@@ -22,7 +22,7 @@ import {
22
22
  PasskeyGetRequest,
23
23
  PasskeyGetResult,
24
24
  } from 'react-native-passkey';
25
- import { Auth, extractAuthInfo, PublicKeyStatus, WalletScheme } from '@getpara/user-management-client';
25
+ import { CurrentWalletIds, PublicKeyStatus, TWalletScheme } from '@getpara/user-management-client';
26
26
  import { setEnv } from '../config.js';
27
27
  import base64url from 'base64url';
28
28
  import { webcrypto } from 'crypto';
@@ -38,6 +38,8 @@ const RS256_ALGORITHM = -257;
38
38
  * const para = new ParaMobile(Environment.BETA, "api_key");
39
39
  */
40
40
  export class ParaMobile extends ParaCore {
41
+ isNativePasskey = true;
42
+
41
43
  private relyingPartyId: string;
42
44
  /**
43
45
  * Creates an instance of ParaMobile.
@@ -49,15 +51,6 @@ export class ParaMobile extends ParaCore {
49
51
  constructor(env: Environment, apiKey: string, relyingPartyId?: string, opts?: ConstructorOpts) {
50
52
  super(env, apiKey, opts);
51
53
 
52
- // starting with non-prod to see what kind of errors we get and if sensitive data is tracked
53
- // will turn on in prod after monitoring
54
- if (env !== Environment.PROD && env !== Environment.DEV) {
55
- Sentry.init({
56
- environment: env.toLowerCase(),
57
- dsn: 'https://59cea0cfbbb30a646c4e9f2feea06da4@o4504568036720640.ingest.us.sentry.io/4508850922323968',
58
- });
59
- }
60
-
61
54
  setEnv(env);
62
55
 
63
56
  if (relyingPartyId) {
@@ -79,44 +72,32 @@ export class ParaMobile extends ParaCore {
79
72
  }
80
73
  }
81
74
 
75
+ protected async ready() {
76
+ this.isReady = true;
77
+ }
78
+
82
79
  protected getPlatformUtils(): PlatformUtils {
83
80
  return new ReactNativeUtils();
84
81
  }
85
82
 
86
- /**
87
- * Verifies an email and returns the biometrics ID.
88
- * @param {string} verificationCode - The verification code sent to the email.
89
- * @returns {Promise<string>} The biometrics ID.
90
- */
91
- async verifyEmailBiometricsId({ verificationCode }: { verificationCode: string }): Promise<string> {
92
- const webAuthCreateUrl = await super.verifyEmail({ verificationCode });
93
- const segments = webAuthCreateUrl.split('/');
94
- const segments2 = segments[segments.length - 1]!.split('?');
95
- const biometricsId = segments2[0]!;
96
-
97
- return biometricsId;
83
+ async isPasskeySupported(): Promise<boolean> {
84
+ return Passkey.isSupported();
98
85
  }
99
86
 
100
- /**
101
- * Verifies a phone number and returns the biometrics ID.
102
- * @param {string} verificationCode - The verification code sent to the phone.
103
- * @returns {Promise<string>} The biometrics ID.
104
- */
105
- async verifyPhoneBiometricsId({ verificationCode }: { verificationCode: string }): Promise<string> {
106
- const webAuthCreateUrl = await super.verifyPhone({ verificationCode });
107
- const segments = webAuthCreateUrl.split('/');
108
- const segments2 = segments[segments.length - 1]!.split('?');
109
- const biometricsId = segments2[0]!;
110
-
111
- return biometricsId;
112
- }
113
87
  /**
114
88
  * Registers a passkey for the user.
115
89
  * @param {Auth<'email'> | Auth<'phone'>} auth - The user's authentication details
116
90
  * @param {string} biometricsId - The biometrics ID obtained from verification.
117
91
  * @returns {Promise<void>}
118
92
  */
119
- async registerPasskey({ biometricsId, ...auth }: { biometricsId: string } & (Auth<'email'> | Auth<'phone'>)) {
93
+ async registerPasskey(authState: AuthStateSignup) {
94
+ if (!authState.passkeyId) {
95
+ throw new Error('Passkey ID not found. Make sure you have enabled passkey logins in the Para Developer Portal.');
96
+ }
97
+
98
+ const userId = this.assertUserId();
99
+ const authInfo = this.assertIsAuthSet();
100
+
120
101
  if (!webcrypto || !webcrypto.getRandomValues) {
121
102
  throw new Error('Web crypto is not available. Ensure you have imported the shim from @getpara/react-native-wallet.');
122
103
  }
@@ -124,8 +105,6 @@ export class ParaMobile extends ParaCore {
124
105
  webcrypto.getRandomValues(userHandle);
125
106
  const userHandleEncoded = base64url.encode(userHandle as any);
126
107
 
127
- const { identifier: displayIdentifier } = extractAuthInfo(auth, { isRequired: true });
128
-
129
108
  const requestJson: PasskeyCreateRequest = {
130
109
  authenticatorSelection: {
131
110
  authenticatorAttachment: 'platform' as any,
@@ -139,8 +118,8 @@ export class ParaMobile extends ParaCore {
139
118
  },
140
119
  user: {
141
120
  id: userHandleEncoded,
142
- name: displayIdentifier,
143
- displayName: displayIdentifier,
121
+ name: authInfo.identifier,
122
+ displayName: authInfo.identifier,
144
123
  },
145
124
  pubKeyCredParams: [
146
125
  {
@@ -175,7 +154,7 @@ export class ParaMobile extends ParaCore {
175
154
  const encryptedPrivateKeyHex = await encryptPrivateKey(keyPair, userHandleEncoded);
176
155
 
177
156
  const { partnerId } = await this.ctx.client.touchSession();
178
- await this.ctx.client.patchSessionPublicKey(partnerId, this.getUserId()!, biometricsId, {
157
+ await this.ctx.client.patchSessionPublicKey(partnerId, userId, authState.passkeyId, {
179
158
  publicKey: resultJson.id,
180
159
  sigDerivedPublicKey: publicKeyHex,
181
160
  cosePublicKey,
@@ -183,12 +162,7 @@ export class ParaMobile extends ParaCore {
183
162
  status: PublicKeyStatus.COMPLETE,
184
163
  });
185
164
 
186
- await this.ctx.client.uploadEncryptedWalletPrivateKey(
187
- this.getUserId()!,
188
- encryptedPrivateKeyHex,
189
- encryptionKeyHash,
190
- resultJson.id,
191
- );
165
+ await this.ctx.client.uploadEncryptedWalletPrivateKey(userId, encryptedPrivateKeyHex, encryptionKeyHash, resultJson.id);
192
166
  }
193
167
 
194
168
  /**
@@ -196,12 +170,11 @@ export class ParaMobile extends ParaCore {
196
170
  * @param {AuthParams} params - The authentication parameters.
197
171
  * @returns {Promise<void>}
198
172
  */
199
- async login({ ...auth }: Auth<'email'> | Auth<'phone'>): Promise<void> {
200
- await this.logout();
173
+ async loginWithPasskey(): Promise<void> {
174
+ this.assertIsAuthSet();
175
+ const userId = this.assertUserId();
201
176
 
202
- const authInfo = extractAuthInfo(auth, { isRequired: true });
203
-
204
- const { challenge, allowedPublicKeys } = await this.ctx.client.getWebChallenge(authInfo.auth);
177
+ const { challenge, allowedPublicKeys } = await this.ctx.client.getWebChallenge({ userId });
205
178
 
206
179
  const requestJson: PasskeyGetRequest = {
207
180
  challenge,
@@ -220,7 +193,7 @@ export class ParaMobile extends ParaCore {
220
193
  resultJson = result;
221
194
  }
222
195
 
223
- const { partnerId } = await this.ctx.client.touchSession();
196
+ const { partnerId, sessionLookupId } = await this.ctx.client.touchSession();
224
197
  const publicKey = resultJson.id;
225
198
  const verifyWebChallengeResult = await this.ctx.client.verifyWebChallenge(partnerId, {
226
199
  publicKey,
@@ -231,22 +204,8 @@ export class ParaMobile extends ParaCore {
231
204
  },
232
205
  });
233
206
 
234
- const userId = verifyWebChallengeResult.data.userId;
235
-
236
- await this.setUserId(userId);
237
-
238
- const { user } = await this.ctx.client.getUser(userId);
239
-
240
- if (user.phone) {
241
- await this.setPhoneNumber(user.phone.number, user.phone.countryCode);
242
- }
243
-
244
- if (user.email) {
245
- await this.setEmail(user.email);
246
- }
247
-
248
- if (user.farcasterUsername) {
249
- await this.setFarcasterUsername(user.farcasterUsername);
207
+ if (userId !== verifyWebChallengeResult.data.userId) {
208
+ throw new Error('User ID mismatch');
250
209
  }
251
210
 
252
211
  const encryptedSharesResult = await this.ctx.client.getBiometricKeyshares(userId, resultJson.id);
@@ -273,7 +232,7 @@ export class ParaMobile extends ParaCore {
273
232
  decryptedShares = await decryptPrivateKeyAndDecryptShare(
274
233
  resultJson.response.userHandle,
275
234
  encryptedSharesResult.data.keyShares,
276
- encryptedPrivateKeys[0].encryptedPrivateKey,
235
+ encryptedPrivateKeys[0]!.encryptedPrivateKey,
277
236
  );
278
237
  }
279
238
 
@@ -288,11 +247,21 @@ export class ParaMobile extends ParaCore {
288
247
  signer: decryptedShare.signer,
289
248
  address: desiredWallet.address || undefined,
290
249
  publicKey: desiredWallet.publicKey || undefined,
291
- scheme: desiredWallet.scheme as WalletScheme,
250
+ scheme: desiredWallet.scheme as TWalletScheme,
292
251
  type: desiredWallet.type || undefined,
293
252
  };
294
253
  }
295
254
 
255
+ const currentWalletIds: CurrentWalletIds = {};
256
+ for (const wallet of Object.values(walletsToInsert)) {
257
+ const { id, type } = wallet;
258
+ const currentIdsForType = currentWalletIds[type || 'EVM'] || [];
259
+ currentWalletIds[type || 'EVM'] = [...currentIdsForType, id];
260
+ }
261
+
296
262
  await this.setWallets(walletsToInsert);
263
+ await this.setCurrentWalletIds(currentWalletIds, {
264
+ sessionLookupId,
265
+ });
297
266
  }
298
267
  }
@@ -1,7 +1,7 @@
1
1
  import { PlatformUtils, TPregenIdentifierType } from '@getpara/web-sdk';
2
2
  import { Ctx } from '@getpara/web-sdk';
3
3
  import { SignatureRes } from '@getpara/web-sdk';
4
- import { BackupKitEmailProps, KeyShareType, WalletScheme, WalletType } from '@getpara/user-management-client';
4
+ import { BackupKitEmailProps, KeyShareType, TWalletType, SDKType } from '@getpara/user-management-client';
5
5
  import { NativeModules } from 'react-native';
6
6
 
7
7
  import { AsyncStorage } from '../AsyncStorage.js';
@@ -55,6 +55,7 @@ async function sendTransactionRequest(
55
55
  }
56
56
 
57
57
  export class ReactNativeUtils implements PlatformUtils {
58
+ sdkType: SDKType = 'REACT_NATIVE';
58
59
  disableProviderModal?: boolean | undefined;
59
60
  localStorage = new AsyncStorage();
60
61
  sessionStorage = new AsyncStorage();
@@ -69,7 +70,7 @@ export class ReactNativeUtils implements PlatformUtils {
69
70
  async keygen(
70
71
  ctx: Ctx,
71
72
  userId: string,
72
- type: Exclude<WalletType, WalletType.SOLANA>,
73
+ type: Exclude<TWalletType, 'SOLANA'>,
73
74
  _secretKey: string | null,
74
75
  _sessionCookie: string,
75
76
  _emailProps?: BackupKitEmailProps | undefined,
@@ -77,7 +78,7 @@ export class ReactNativeUtils implements PlatformUtils {
77
78
  const { walletId, protocolId } = await ctx.client.createWallet(userId, {
78
79
  type,
79
80
  useTwoSigners: true,
80
- scheme: ctx.useDKLS ? WalletScheme.DKLS : WalletScheme.CGGMP,
81
+ scheme: ctx.useDKLS ? 'DKLS' : 'CGGMP',
81
82
  });
82
83
 
83
84
  if (ctx.mpcComputationClient && !ctx.useDKLS) {
@@ -220,8 +221,8 @@ export class ReactNativeUtils implements PlatformUtils {
220
221
  walletId: string;
221
222
  }> {
222
223
  const { walletId, protocolId } = await ctx.client.createWallet(userId, {
223
- scheme: WalletScheme.ED25519,
224
- type: WalletType.SOLANA,
224
+ scheme: 'ED25519',
225
+ type: 'SOLANA',
225
226
  });
226
227
 
227
228
  const signer = await ParaSignerModule.ed25519CreateAccount(walletId, protocolId);
@@ -240,8 +241,8 @@ export class ReactNativeUtils implements PlatformUtils {
240
241
  const { walletId, protocolId } = await ctx.client.createPregenWallet({
241
242
  pregenIdentifier,
242
243
  pregenIdentifierType,
243
- scheme: WalletScheme.ED25519,
244
- type: WalletType.SOLANA,
244
+ scheme: 'ED25519',
245
+ type: 'SOLANA',
245
246
  });
246
247
 
247
248
  const signer = await ParaSignerModule.ed25519CreateAccount(walletId, protocolId);
@@ -256,7 +257,7 @@ export class ReactNativeUtils implements PlatformUtils {
256
257
  base64Bytes: string,
257
258
  _sessionCookie: string,
258
259
  ): Promise<SignatureRes> {
259
- const { protocolId } = await ctx.client.preSignMessage(userId, walletId, base64Bytes, WalletScheme.ED25519);
260
+ const { protocolId } = await ctx.client.preSignMessage(userId, walletId, base64Bytes, 'ED25519');
260
261
 
261
262
  const base64Sig = await ParaSignerModule.ed25519Sign(protocolId, share, base64Bytes);
262
263
  return { signature: base64Sig };
package/src/shim.js CHANGED
@@ -8,6 +8,7 @@ import { Buffer } from '@craftzdog/react-native-buffer';
8
8
  import process from 'process';
9
9
  import 'react-native-url-polyfill/auto';
10
10
  import { TextEncoder, TextDecoder } from 'text-encoding';
11
+ import structuredClone from '@ungap/structured-clone';
11
12
 
12
13
  const setupProcessPolyfill = () => {
13
14
  if (typeof globalThis.process === 'undefined') {
@@ -67,8 +68,15 @@ const setupTextEncodingPolyfills = () => {
67
68
  globalThis.TextDecoder = TextDecoder;
68
69
  };
69
70
 
71
+ const setupStructuredClonePolyfill = () => {
72
+ if (typeof globalThis.structuredClone === 'undefined') {
73
+ globalThis.structuredClone = structuredClone;
74
+ }
75
+ };
76
+
70
77
  setupProcessPolyfill();
71
78
  setupBufferPolyfill();
72
79
  setupBase64Polyfills();
73
80
  setupCryptoPolyfills();
74
81
  setupTextEncodingPolyfills();
82
+ setupStructuredClonePolyfill();
File without changes