@getpara/react-native-wallet 2.16.0 → 2.18.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/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export * from '@getpara/web-sdk';
2
2
  export { ParaMobile } from './react-native/ParaMobile.js';
3
- export * from '@getpara/viem-v2-integration';
3
+ export * from '@getpara/viem-v2-integration/aa';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from '@getpara/web-sdk';
2
2
  export { ParaMobile } from './react-native/ParaMobile.js';
3
- // Smart Account types, errors, utilities — re-exported from viem-v2-integration
4
- export * from '@getpara/viem-v2-integration';
3
+ // Smart Account types, errors, utilities — re-exported from viem-v2-integration/aa
4
+ export * from '@getpara/viem-v2-integration/aa';
@@ -34,6 +34,18 @@ export declare class ParaMobile extends ParaCore {
34
34
  * @returns {Promise<void>}
35
35
  */
36
36
  loginWithPasskey(): Promise<void>;
37
+ /**
38
+ * Sets a global handler for transaction review URLs. When a signing operation requires
39
+ * user approval (e.g., due to permissions policies), the SDK needs to open a review URL.
40
+ * On React Native, provide a handler that opens the URL in an in-app browser.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * import { openBrowserAsync } from 'expo-web-browser';
45
+ * para.setTransactionReviewHandler((url) => openBrowserAsync(url));
46
+ * ```
47
+ */
48
+ setTransactionReviewHandler(handler: (url: string) => void): void;
37
49
  /**
38
50
  * Handles a message from an in-app browser (WebView).
39
51
  * Call this from your WebView's `onMessage` callback to bridge portal events
@@ -256,6 +256,20 @@ export class ParaMobile extends ParaCore {
256
256
  });
257
257
  });
258
258
  }
259
+ /**
260
+ * Sets a global handler for transaction review URLs. When a signing operation requires
261
+ * user approval (e.g., due to permissions policies), the SDK needs to open a review URL.
262
+ * On React Native, provide a handler that opens the URL in an in-app browser.
263
+ *
264
+ * @example
265
+ * ```ts
266
+ * import { openBrowserAsync } from 'expo-web-browser';
267
+ * para.setTransactionReviewHandler((url) => openBrowserAsync(url));
268
+ * ```
269
+ */
270
+ setTransactionReviewHandler(handler) {
271
+ this.platformUtils.transactionReviewHandler = handler;
272
+ }
259
273
  /**
260
274
  * Handles a message from an in-app browser (WebView).
261
275
  * Call this from your WebView's `onMessage` callback to bridge portal events
@@ -11,6 +11,7 @@ export declare class ReactNativeUtils implements PlatformUtils {
11
11
  sessionStorage: AsyncStorage;
12
12
  secureStorage: KeychainStorage;
13
13
  isSyncStorage: boolean;
14
+ transactionReviewHandler?: (url: string) => void;
14
15
  private eventHandlers;
15
16
  addEventListener<T = EventData>({ event, handler }: {
16
17
  ctx: Ctx;
@@ -45,7 +46,7 @@ export declare class ReactNativeUtils implements PlatformUtils {
45
46
  walletId: string;
46
47
  }>;
47
48
  getPrivateKey(_ctx: Ctx, _userId: string, _walletId: string, _share: string, _sessionCookie: string): Promise<string>;
48
- openPopup(_popupUrl: string): any;
49
+ openPopup(popupUrl: string): any;
49
50
  private baseSignTransaction;
50
51
  sendTransaction(ctx: Ctx, userId: string, walletId: string, share: string, rlpEncodedTxBase64: string, chainId: string, _sessionCookie: string, isDKLS?: boolean): Promise<SignatureRes>;
51
52
  signHash(_address: string, _hash: string): Promise<{
@@ -118,8 +118,12 @@ export class ReactNativeUtils {
118
118
  getPrivateKey(_ctx, _userId, _walletId, _share, _sessionCookie) {
119
119
  throw new Error('Method not implemented.');
120
120
  }
121
- openPopup(_popupUrl) {
122
- throw new Error('Method not implemented.');
121
+ openPopup(popupUrl) {
122
+ if (this.transactionReviewHandler) {
123
+ this.transactionReviewHandler(popupUrl);
124
+ return;
125
+ }
126
+ throw new Error('openPopup is not supported on React Native. Use setTransactionReviewHandler() to handle transaction review URLs.');
123
127
  }
124
128
  baseSignTransaction(ctx, userId, walletId, protocolId, share, rlpEncodedTxBase64, chainId, isDKLS) {
125
129
  return __awaiter(this, void 0, void 0, function* () {
@@ -135,11 +139,14 @@ export class ReactNativeUtils {
135
139
  }
136
140
  sendTransaction(ctx, userId, walletId, share, rlpEncodedTxBase64, chainId, _sessionCookie, isDKLS) {
137
141
  return __awaiter(this, void 0, void 0, function* () {
138
- const { protocolId } = (yield ctx.client.sendTransaction(userId, walletId, {
142
+ const { data } = yield ctx.client.sendTransaction(userId, walletId, {
139
143
  transaction: rlpEncodedTxBase64,
140
144
  chainId,
141
- })).data;
142
- return this.baseSignTransaction(ctx, userId, walletId, protocolId, share, rlpEncodedTxBase64, chainId, isDKLS);
145
+ });
146
+ if (data.pendingTransactionId) {
147
+ return { pendingTransactionId: data.pendingTransactionId };
148
+ }
149
+ return this.baseSignTransaction(ctx, userId, walletId, data.protocolId, share, rlpEncodedTxBase64, chainId, isDKLS);
143
150
  });
144
151
  }
145
152
  signHash(_address, _hash) {
@@ -151,6 +158,9 @@ export class ReactNativeUtils {
151
158
  _sessionCookie, isDKLS) {
152
159
  return __awaiter(this, void 0, void 0, function* () {
153
160
  const res = yield ctx.client.preSignMessage(userId, walletId, messageBase64);
161
+ if (res.pendingTransactionId) {
162
+ return { pendingTransactionId: res.pendingTransactionId };
163
+ }
154
164
  if (ctx.mpcComputationClient && !isDKLS) {
155
165
  const signature = (yield signMessageRequest(ctx, userId, walletId, res.protocolId, messageBase64, share)).signature;
156
166
  return { signature };
@@ -166,11 +176,14 @@ export class ReactNativeUtils {
166
176
  signTransaction(ctx, userId, walletId, share, rlpEncodedTxBase64, // base64 encoding of rlp encoded tx
167
177
  chainId, _sessionCookie, isDKLS) {
168
178
  return __awaiter(this, void 0, void 0, function* () {
169
- const { protocolId } = (yield ctx.client.signTransaction(userId, walletId, {
179
+ const { data } = yield ctx.client.signTransaction(userId, walletId, {
170
180
  transaction: rlpEncodedTxBase64,
171
181
  chainId,
172
- })).data;
173
- return this.baseSignTransaction(ctx, userId, walletId, protocolId, share, rlpEncodedTxBase64, chainId, isDKLS);
182
+ });
183
+ if (data.pendingTransactionId) {
184
+ return { pendingTransactionId: data.pendingTransactionId };
185
+ }
186
+ return this.baseSignTransaction(ctx, userId, walletId, data.protocolId, share, rlpEncodedTxBase64, chainId, isDKLS);
174
187
  });
175
188
  }
176
189
  ed25519Keygen(ctx, userId, _sessionCookie, _emailProps) {
@@ -197,8 +210,11 @@ export class ReactNativeUtils {
197
210
  }
198
211
  ed25519Sign(ctx, userId, walletId, share, base64Bytes, _sessionCookie) {
199
212
  return __awaiter(this, void 0, void 0, function* () {
200
- const { protocolId } = yield ctx.client.preSignMessage(userId, walletId, base64Bytes, 'ED25519');
201
- const base64Sig = yield ParaSignerModule.ed25519Sign(protocolId, share, base64Bytes);
213
+ const res = yield ctx.client.preSignMessage(userId, walletId, base64Bytes, 'ED25519');
214
+ if (res.pendingTransactionId) {
215
+ return { pendingTransactionId: res.pendingTransactionId };
216
+ }
217
+ const base64Sig = yield ParaSignerModule.ed25519Sign(res.protocolId, share, base64Bytes);
202
218
  return { signature: base64Sig };
203
219
  });
204
220
  }
package/dist/shim.d.ts CHANGED
@@ -23,7 +23,7 @@ export function ensureParaCrypto(): {
23
23
  pseudoRandomBytes: typeof import("react-native-quick-crypto/lib/typescript/src/random").randomBytes;
24
24
  prng: typeof import("react-native-quick-crypto/lib/typescript/src/random").randomBytes;
25
25
  pbkdf2(password: import("react-native-quick-crypto/lib/typescript/src/Utils").BinaryLike, salt: import("react-native-quick-crypto/lib/typescript/src/Utils").BinaryLike, iterations: number, keylen: number, digest: string, callback: (err: Error | null, derivedKey?: Buffer) => void): void;
26
- pbkdf2Sync(password: import("react-native-quick-crypto/lib/typescript/src/Utils").BinaryLike, salt: import("react-native-quick-crypto/lib/typescript/src/Utils").BinaryLike, iterations: number, keylen: number, digest?: string): ArrayBuffer;
26
+ pbkdf2Sync(password: import("react-native-quick-crypto/lib/typescript/src/Utils").BinaryLike, salt: import("react-native-quick-crypto/lib/typescript/src/Utils").BinaryLike, iterations: number, keylen: number, digest?: string): Buffer;
27
27
  pbkdf2DeriveBits(algorithm: import("react-native-quick-crypto/lib/typescript/src/keys").SubtleAlgorithm, baseKey: import("react-native-quick-crypto/lib/typescript/src/keys").CryptoKey, length: number): Promise<ArrayBuffer>;
28
28
  createHmac: typeof import("react-native-quick-crypto/lib/typescript/src/Hmac").createHmac;
29
29
  Hmac: typeof import("react-native-quick-crypto/lib/typescript/src/Hmac").createHmac;
package/package.json CHANGED
@@ -1,30 +1,30 @@
1
1
  {
2
2
  "name": "@getpara/react-native-wallet",
3
3
  "description": "Para Wallet for React Native",
4
- "version": "2.16.0",
4
+ "version": "2.18.0",
5
5
  "author": "Para Team <hello@getpara.com> (https://getpara.com)",
6
6
  "dependencies": {
7
- "@getpara/core-sdk": "2.16.0",
8
- "@getpara/user-management-client": "2.16.0",
9
- "@getpara/viem-v2-integration": "2.16.0",
10
- "@getpara/web-sdk": "2.16.0",
7
+ "@getpara/core-sdk": "2.18.0",
8
+ "@getpara/user-management-client": "2.18.0",
9
+ "@getpara/viem-v2-integration": "2.18.0",
10
+ "@getpara/web-sdk": "2.18.0",
11
11
  "@peculiar/webcrypto": "^1.5.0",
12
12
  "@ungap/structured-clone": "1.3.0",
13
13
  "react-native-url-polyfill": "2.0.0",
14
14
  "text-encoding": "0.7.0"
15
15
  },
16
16
  "devDependencies": {
17
- "@craftzdog/react-native-buffer": "6.0.5",
18
- "@react-native-async-storage/async-storage": "2.1.2",
19
- "@types/node-forge": "1.3.1",
20
- "@types/react": "^18.0.31",
17
+ "@craftzdog/react-native-buffer": "^6.1.0",
18
+ "@react-native-async-storage/async-storage": "^2.2.0",
19
+ "@types/node-forge": "^1.3.11",
20
+ "@types/react": "^18.3.3",
21
21
  "@types/react-native": "0.70.0",
22
22
  "@types/text-encoding": "0.0.39",
23
- "react-native-keychain": "10.0.0",
24
- "react-native-modpow": "1.1.0",
25
- "react-native-passkey": "3.1.0",
26
- "react-native-quick-base64": "2.1.2",
27
- "react-native-quick-crypto": "0.7.12",
23
+ "react-native-keychain": "^10.0.0",
24
+ "react-native-modpow": "^1.1.0",
25
+ "react-native-passkey": "^3.1.0",
26
+ "react-native-quick-base64": "^2.2.0",
27
+ "react-native-quick-crypto": "^0.7.14",
28
28
  "typescript": "^5.8.3"
29
29
  },
30
30
  "exports": {
@@ -52,16 +52,16 @@
52
52
  "main": "./dist/index.js",
53
53
  "module": "./dist/index.js",
54
54
  "peerDependencies": {
55
- "@craftzdog/react-native-buffer": "*",
56
- "@react-native-async-storage/async-storage": "*",
57
- "react": "*",
58
- "react-native": "*",
59
- "react-native-keychain": "*",
60
- "react-native-modpow": "*",
61
- "react-native-passkey": "*",
62
- "react-native-quick-base64": "*",
63
- "react-native-quick-crypto": "*",
64
- "readable-stream": "*"
55
+ "@craftzdog/react-native-buffer": ">=6.0.0",
56
+ "@react-native-async-storage/async-storage": ">=2.0.0",
57
+ "react": ">=18",
58
+ "react-native": ">=0.70.0",
59
+ "react-native-keychain": ">=8.0.0",
60
+ "react-native-modpow": ">=1.0.0",
61
+ "react-native-passkey": ">=3.0.0",
62
+ "react-native-quick-base64": ">=2.0.0",
63
+ "react-native-quick-crypto": ">=0.7.0",
64
+ "readable-stream": ">=4.0.0"
65
65
  },
66
66
  "publishConfig": {
67
67
  "access": "public"
@@ -93,5 +93,5 @@
93
93
  ]
94
94
  }
95
95
  },
96
- "gitHead": "fbe96a062b308d04105213378c12c38ee973c798"
96
+ "gitHead": "4481f6f4e108e682d14c74d4433696141c47fc58"
97
97
  }
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from '@getpara/web-sdk';
2
2
  export { ParaMobile } from './react-native/ParaMobile.js';
3
3
 
4
- // Smart Account types, errors, utilities — re-exported from viem-v2-integration
5
- export * from '@getpara/viem-v2-integration';
4
+ // Smart Account types, errors, utilities — re-exported from viem-v2-integration/aa
5
+ export * from '@getpara/viem-v2-integration/aa';
@@ -326,6 +326,21 @@ export class ParaMobile extends ParaCore {
326
326
  });
327
327
  }
328
328
 
329
+ /**
330
+ * Sets a global handler for transaction review URLs. When a signing operation requires
331
+ * user approval (e.g., due to permissions policies), the SDK needs to open a review URL.
332
+ * On React Native, provide a handler that opens the URL in an in-app browser.
333
+ *
334
+ * @example
335
+ * ```ts
336
+ * import { openBrowserAsync } from 'expo-web-browser';
337
+ * para.setTransactionReviewHandler((url) => openBrowserAsync(url));
338
+ * ```
339
+ */
340
+ setTransactionReviewHandler(handler: (url: string) => void): void {
341
+ (this.platformUtils as ReactNativeUtils).transactionReviewHandler = handler;
342
+ }
343
+
329
344
  /**
330
345
  * Handles a message from an in-app browser (WebView).
331
346
  * Call this from your WebView's `onMessage` callback to bridge portal events
@@ -62,6 +62,8 @@ export class ReactNativeUtils implements PlatformUtils {
62
62
  secureStorage = new KeychainStorage();
63
63
  isSyncStorage = false;
64
64
 
65
+ transactionReviewHandler?: (url: string) => void;
66
+
65
67
  private eventHandlers = new Map<string, Set<EventHandler>>();
66
68
 
67
69
  addEventListener<T = EventData>({ event, handler }: { ctx: Ctx; event: string; handler: EventHandler<T> }): void {
@@ -158,8 +160,14 @@ export class ReactNativeUtils implements PlatformUtils {
158
160
  throw new Error('Method not implemented.');
159
161
  }
160
162
 
161
- openPopup(_popupUrl: string): any {
162
- throw new Error('Method not implemented.');
163
+ openPopup(popupUrl: string): any {
164
+ if (this.transactionReviewHandler) {
165
+ this.transactionReviewHandler(popupUrl);
166
+ return;
167
+ }
168
+ throw new Error(
169
+ 'openPopup is not supported on React Native. Use setTransactionReviewHandler() to handle transaction review URLs.',
170
+ );
163
171
  }
164
172
 
165
173
  private async baseSignTransaction(
@@ -193,13 +201,16 @@ export class ReactNativeUtils implements PlatformUtils {
193
201
  _sessionCookie: string,
194
202
  isDKLS?: boolean,
195
203
  ): Promise<SignatureRes> {
196
- const { protocolId } = (
197
- await ctx.client.sendTransaction(userId, walletId, {
198
- transaction: rlpEncodedTxBase64,
199
- chainId,
200
- })
201
- ).data;
202
- return this.baseSignTransaction(ctx, userId, walletId, protocolId, share, rlpEncodedTxBase64, chainId, isDKLS);
204
+ const { data } = await ctx.client.sendTransaction(userId, walletId, {
205
+ transaction: rlpEncodedTxBase64,
206
+ chainId,
207
+ });
208
+
209
+ if (data.pendingTransactionId) {
210
+ return { pendingTransactionId: data.pendingTransactionId };
211
+ }
212
+
213
+ return this.baseSignTransaction(ctx, userId, walletId, data.protocolId, share, rlpEncodedTxBase64, chainId, isDKLS);
203
214
  }
204
215
 
205
216
  async signHash(_address: string, _hash: string): Promise<{ v: number; r: Buffer; s: Buffer }> {
@@ -217,6 +228,10 @@ export class ReactNativeUtils implements PlatformUtils {
217
228
  ): Promise<SignatureRes> {
218
229
  const res = await ctx.client.preSignMessage(userId, walletId, messageBase64);
219
230
 
231
+ if (res.pendingTransactionId) {
232
+ return { pendingTransactionId: res.pendingTransactionId };
233
+ }
234
+
220
235
  if (ctx.mpcComputationClient && !isDKLS) {
221
236
  const signature = (await signMessageRequest(ctx, userId, walletId, res.protocolId, messageBase64, share)).signature;
222
237
  return { signature };
@@ -241,13 +256,16 @@ export class ReactNativeUtils implements PlatformUtils {
241
256
  _sessionCookie: string,
242
257
  isDKLS?: boolean,
243
258
  ): Promise<SignatureRes> {
244
- const { protocolId } = (
245
- await ctx.client.signTransaction(userId, walletId, {
246
- transaction: rlpEncodedTxBase64,
247
- chainId,
248
- })
249
- ).data;
250
- return this.baseSignTransaction(ctx, userId, walletId, protocolId, share, rlpEncodedTxBase64, chainId, isDKLS);
259
+ const { data } = await ctx.client.signTransaction(userId, walletId, {
260
+ transaction: rlpEncodedTxBase64,
261
+ chainId,
262
+ });
263
+
264
+ if (data.pendingTransactionId) {
265
+ return { pendingTransactionId: data.pendingTransactionId };
266
+ }
267
+
268
+ return this.baseSignTransaction(ctx, userId, walletId, data.protocolId, share, rlpEncodedTxBase64, chainId, isDKLS);
251
269
  }
252
270
 
253
271
  async ed25519Keygen(
@@ -296,9 +314,13 @@ export class ReactNativeUtils implements PlatformUtils {
296
314
  base64Bytes: string,
297
315
  _sessionCookie: string,
298
316
  ): Promise<SignatureRes> {
299
- const { protocolId } = await ctx.client.preSignMessage(userId, walletId, base64Bytes, 'ED25519');
317
+ const res = await ctx.client.preSignMessage(userId, walletId, base64Bytes, 'ED25519');
318
+
319
+ if (res.pendingTransactionId) {
320
+ return { pendingTransactionId: res.pendingTransactionId };
321
+ }
300
322
 
301
- const base64Sig = await ParaSignerModule.ed25519Sign(protocolId, share, base64Bytes);
323
+ const base64Sig = await ParaSignerModule.ed25519Sign(res.protocolId, share, base64Bytes);
302
324
  return { signature: base64Sig };
303
325
  }
304
326