@etherplay/connect 0.0.37 → 0.0.39

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/src/index.ts CHANGED
@@ -83,12 +83,14 @@ type WaitingForSignature<WalletProviderType> = {
83
83
  step: 'WaitingForSignature';
84
84
  mechanism: WalletMechanism<string, `0x${string}`>;
85
85
  wallet: WalletState<WalletProviderType>;
86
+ account: {address: `0x${string}`};
86
87
  };
87
88
 
88
89
  type WalletConnected<WalletProviderType> = {
89
90
  step: 'WalletConnected';
90
91
  mechanism: WalletMechanism<string, `0x${string}`>;
91
92
  wallet: WalletState<WalletProviderType>;
93
+ account: {address: `0x${string}`};
92
94
  };
93
95
 
94
96
  type SignedIn<WalletProviderType> =
@@ -237,12 +239,16 @@ function viemChainInfoToSwitchChainInfo(chainInfo: BasicChainInfo): {
237
239
  const storageKeyAccount = '__origin_account';
238
240
  const storageKeyLastWallet = '__last_wallet';
239
241
 
240
- export type ConnectionOptions = {
242
+ export type ConnectOptions = {
241
243
  requireUserConfirmationBeforeSignatureRequest?: boolean;
242
244
  doNotStoreLocally?: boolean;
243
245
  requestSignatureRightAway?: boolean;
244
246
  };
245
247
 
248
+ export type EnsureConnectedOptions = ConnectOptions & {
249
+ skipChainCheck?: boolean; // Skip chain validation for WalletConnected step
250
+ };
251
+
246
252
  export type ConnectionStore<
247
253
  WalletProviderType,
248
254
  Target extends TargetStep = 'SignedIn',
@@ -255,7 +261,7 @@ export type ConnectionStore<
255
261
  : WalletOnly extends true
256
262
  ? WalletMechanism<string | undefined, `0x${string}` | undefined>
257
263
  : Mechanism,
258
- options?: ConnectionOptions,
264
+ options?: ConnectOptions,
259
265
  ) => Promise<void>;
260
266
  cancel: () => void;
261
267
  back: (step: 'MechanismToChoose' | 'Idle' | 'WalletToChoose') => void;
@@ -272,36 +278,40 @@ export type ConnectionStore<
272
278
  // ensureConnected signature depends on target and walletOnly
273
279
  ensureConnected: Target extends 'WalletConnected'
274
280
  ? {
275
- (options?: ConnectionOptions): Promise<WalletConnected<WalletProviderType>>;
281
+ (options?: EnsureConnectedOptions): Promise<WalletConnected<WalletProviderType>>;
276
282
  (
277
283
  step: 'WalletConnected',
278
284
  mechanism?: WalletMechanism<string | undefined, `0x${string}` | undefined>,
279
- options?: ConnectionOptions,
285
+ options?: EnsureConnectedOptions,
280
286
  ): Promise<WalletConnected<WalletProviderType>>;
281
287
  }
282
288
  : WalletOnly extends true
283
289
  ? {
284
290
  // walletOnly: true for SignedIn - returns SignedInWithWallet (not full SignedIn union)
285
- (options?: ConnectionOptions): Promise<SignedInWithWallet<WalletProviderType>>;
291
+ (options?: EnsureConnectedOptions): Promise<SignedInWithWallet<WalletProviderType>>;
286
292
  (
287
293
  step: 'WalletConnected',
288
294
  mechanism?: WalletMechanism<string | undefined, `0x${string}` | undefined>,
289
- options?: ConnectionOptions,
295
+ options?: EnsureConnectedOptions,
290
296
  ): Promise<WalletConnected<WalletProviderType>>;
291
297
  (
292
298
  step: 'SignedIn',
293
299
  mechanism?: WalletMechanism<string | undefined, `0x${string}` | undefined>,
294
- options?: ConnectionOptions,
300
+ options?: EnsureConnectedOptions,
295
301
  ): Promise<SignedInWithWallet<WalletProviderType>>;
296
302
  }
297
303
  : {
298
- (options?: ConnectionOptions): Promise<SignedIn<WalletProviderType>>;
304
+ (options?: EnsureConnectedOptions): Promise<SignedIn<WalletProviderType>>;
299
305
  (
300
306
  step: 'WalletConnected',
301
307
  mechanism?: WalletMechanism<string | undefined, `0x${string}` | undefined>,
302
- options?: ConnectionOptions,
308
+ options?: EnsureConnectedOptions,
303
309
  ): Promise<WalletConnected<WalletProviderType>>;
304
- (step: 'SignedIn', mechanism?: Mechanism, options?: ConnectionOptions): Promise<SignedIn<WalletProviderType>>;
310
+ (
311
+ step: 'SignedIn',
312
+ mechanism?: Mechanism,
313
+ options?: EnsureConnectedOptions,
314
+ ): Promise<SignedIn<WalletProviderType>>;
305
315
  };
306
316
 
307
317
  // Method to check if target step is reached with proper type narrowing
@@ -323,6 +333,12 @@ export type ConnectionStore<
323
333
  chainInfo: ChainInfo<WalletProviderType>;
324
334
  };
325
335
 
336
+ export type AnyConnectionStore<WalletProviderType> =
337
+ | ConnectionStore<WalletProviderType, 'SignedIn', true>
338
+ | ConnectionStore<WalletProviderType, 'WalletConnected', true>
339
+ | ConnectionStore<WalletProviderType, 'SignedIn', false>
340
+ | ConnectionStore<WalletProviderType, 'WalletConnected', false>;
341
+
326
342
  // Function overloads for proper typing
327
343
 
328
344
  // WalletConnected target with custom wallet connector - walletHost optional
@@ -592,6 +608,7 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
592
608
  invalidChainId: alwaysOnChainId != chainId,
593
609
  switchingChain: false,
594
610
  },
611
+ account: {address: lastWallet.address},
595
612
  });
596
613
  alwaysOnProviderWrapper.setWalletStatus('connected');
597
614
  onAccountChanged(accounts);
@@ -895,14 +912,8 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
895
912
  walletProvider.stopListenForChainChanged(onChainChanged);
896
913
  }
897
914
 
898
- type ConnectionOptions = {
899
- requireUserConfirmationBeforeSignatureRequest?: boolean;
900
- doNotStoreLocally?: boolean;
901
- requestSignatureRightAway?: boolean;
902
- };
903
-
904
915
  let remember: boolean = false;
905
- async function connect(mechanism?: Mechanism, options?: ConnectionOptions) {
916
+ async function connect(mechanism?: Mechanism, options?: ConnectOptions) {
906
917
  if (!mechanism && (targetStep === 'WalletConnected' || walletOnly)) {
907
918
  mechanism = {type: 'wallet'};
908
919
  }
@@ -1002,6 +1013,7 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
1002
1013
  invalidChainId: alwaysOnChainId != chainId,
1003
1014
  switchingChain: false,
1004
1015
  },
1016
+ account: {address: account},
1005
1017
  };
1006
1018
  if (
1007
1019
  newState.step === 'WalletConnected' &&
@@ -1077,6 +1089,7 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
1077
1089
  invalidChainId: alwaysOnChainId != chainId,
1078
1090
  switchingChain: false,
1079
1091
  },
1092
+ account: {address: account},
1080
1093
  };
1081
1094
  if (
1082
1095
  newState.step === 'WalletConnected' &&
@@ -1186,43 +1199,49 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
1186
1199
 
1187
1200
  // ensureConnected overloads - the default step depends on targetStep
1188
1201
  function ensureConnected(
1189
- options?: ConnectionOptions,
1202
+ options?: EnsureConnectedOptions,
1190
1203
  ): Promise<WalletConnected<WalletProviderType> | SignedIn<WalletProviderType>>;
1191
1204
  function ensureConnected(
1192
1205
  step: 'WalletConnected',
1193
- mechanism?: WalletMechanism<string | undefined, `0x${string}` | undefined>,
1194
- options?: ConnectionOptions,
1206
+ mechanismOrOptions?: WalletMechanism<string | undefined, `0x${string}` | undefined> | EnsureConnectedOptions,
1207
+ options?: EnsureConnectedOptions,
1195
1208
  ): Promise<WalletConnected<WalletProviderType>>;
1196
1209
  function ensureConnected(
1197
1210
  step: 'SignedIn',
1198
1211
  mechanism?: Mechanism,
1199
- options?: ConnectionOptions,
1212
+ options?: EnsureConnectedOptions,
1200
1213
  ): Promise<SignedIn<WalletProviderType>>;
1201
1214
  async function ensureConnected<Step extends 'WalletConnected' | 'SignedIn'>(
1202
- stepOrMechanismOrOptions?: Step | Mechanism | ConnectionOptions,
1203
- mechanismOrOptions?: Mechanism | ConnectionOptions,
1204
- options?: ConnectionOptions,
1215
+ stepOrMechanismOrOptions?: Step | Mechanism | EnsureConnectedOptions,
1216
+ mechanismOrOptions?: Mechanism | EnsureConnectedOptions,
1217
+ options?: EnsureConnectedOptions,
1205
1218
  ): Promise<WalletConnected<WalletProviderType> | SignedIn<WalletProviderType>> {
1206
1219
  // Determine if first arg is a step string, mechanism, or options
1207
1220
  let step: 'WalletConnected' | 'SignedIn';
1208
1221
  let mechanism: Mechanism | undefined;
1209
- let opts: ConnectionOptions | undefined;
1222
+ let opts: EnsureConnectedOptions | undefined;
1210
1223
 
1211
1224
  if (typeof stepOrMechanismOrOptions === 'string') {
1212
1225
  // First arg is a step
1213
1226
  step = stepOrMechanismOrOptions as 'WalletConnected' | 'SignedIn';
1214
- mechanism = mechanismOrOptions as Mechanism | undefined;
1215
- opts = options;
1227
+ // Check if second arg is a mechanism (has 'type') or options (doesn't have 'type')
1228
+ if (mechanismOrOptions && 'type' in (mechanismOrOptions as any)) {
1229
+ mechanism = mechanismOrOptions as Mechanism;
1230
+ opts = options;
1231
+ } else {
1232
+ mechanism = undefined;
1233
+ opts = mechanismOrOptions as EnsureConnectedOptions | undefined;
1234
+ }
1216
1235
  } else if (stepOrMechanismOrOptions && 'type' in (stepOrMechanismOrOptions as any)) {
1217
1236
  // First arg is a mechanism
1218
1237
  step = targetStep; // Use configured target as default
1219
1238
  mechanism = stepOrMechanismOrOptions as Mechanism;
1220
- opts = mechanismOrOptions as ConnectionOptions | undefined;
1239
+ opts = mechanismOrOptions as EnsureConnectedOptions | undefined;
1221
1240
  } else {
1222
1241
  // First arg is options or undefined
1223
1242
  step = targetStep; // Use configured target as default
1224
1243
  mechanism = undefined;
1225
- opts = stepOrMechanismOrOptions as ConnectionOptions | undefined;
1244
+ opts = stepOrMechanismOrOptions as EnsureConnectedOptions | undefined;
1226
1245
  }
1227
1246
 
1228
1247
  // For WalletConnected step, default to wallet mechanism
@@ -1233,13 +1252,31 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
1233
1252
  const promise = new Promise<WalletConnected<WalletProviderType> | SignedIn<WalletProviderType>>(
1234
1253
  (resolve, reject) => {
1235
1254
  let forceConnect = false;
1255
+
1256
+ // Helper to check if resolution conditions are met
1257
+ const canResolve = (connection: Connection<WalletProviderType>): boolean => {
1258
+ // Must be at the target step
1259
+ if (connection.step !== step) return false;
1260
+
1261
+ // For WalletConnected step, check chain validity unless skipped
1262
+ if (step === 'WalletConnected' && !opts?.skipChainCheck) {
1263
+ // connection.wallet should exist when step is WalletConnected
1264
+ if (connection.wallet?.invalidChainId) {
1265
+ return false; // Wrong chain, wait for chain change
1266
+ }
1267
+ }
1268
+
1269
+ return true;
1270
+ };
1271
+
1236
1272
  if (
1237
1273
  $connection.step == 'WalletConnected' &&
1238
1274
  ($connection.wallet.status == 'locked' || $connection.wallet.status === 'disconnected')
1239
1275
  ) {
1240
1276
  forceConnect = true;
1241
1277
  mechanism = $connection.mechanism; // we reuse existing mechanism as we just want to reconnect
1242
- } else if ($connection.step == step) {
1278
+ } else if (canResolve($connection)) {
1279
+ // Only resolve if step matches AND chain is valid (or skipChainCheck)
1243
1280
  resolve($connection as any);
1244
1281
  return;
1245
1282
  }
@@ -1248,14 +1285,16 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
1248
1285
  connect(mechanism, opts);
1249
1286
  }
1250
1287
  const unsubscribe = _store.subscribe((connection) => {
1288
+ // Reject on disconnect/back to Idle
1251
1289
  if (connection.step === 'Idle' && idlePassed) {
1252
1290
  unsubscribe();
1253
- reject();
1291
+ reject(new Error('Connection cancelled'));
1254
1292
  }
1255
1293
  if (!idlePassed && connection.step !== 'Idle') {
1256
1294
  idlePassed = true;
1257
1295
  }
1258
- if (connection.step === step) {
1296
+ // Check full resolution conditions including chain validity
1297
+ if (canResolve(connection)) {
1259
1298
  unsubscribe();
1260
1299
  resolve(connection as any);
1261
1300
  }