@etherplay/connect 0.0.38 → 0.0.40

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
@@ -598,6 +608,7 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
598
608
  invalidChainId: alwaysOnChainId != chainId,
599
609
  switchingChain: false,
600
610
  },
611
+ account: {address: lastWallet.address},
601
612
  });
602
613
  alwaysOnProviderWrapper.setWalletStatus('connected');
603
614
  onAccountChanged(accounts);
@@ -901,14 +912,8 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
901
912
  walletProvider.stopListenForChainChanged(onChainChanged);
902
913
  }
903
914
 
904
- type ConnectionOptions = {
905
- requireUserConfirmationBeforeSignatureRequest?: boolean;
906
- doNotStoreLocally?: boolean;
907
- requestSignatureRightAway?: boolean;
908
- };
909
-
910
915
  let remember: boolean = false;
911
- async function connect(mechanism?: Mechanism, options?: ConnectionOptions) {
916
+ async function connect(mechanism?: Mechanism, options?: ConnectOptions) {
912
917
  if (!mechanism && (targetStep === 'WalletConnected' || walletOnly)) {
913
918
  mechanism = {type: 'wallet'};
914
919
  }
@@ -1008,6 +1013,7 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
1008
1013
  invalidChainId: alwaysOnChainId != chainId,
1009
1014
  switchingChain: false,
1010
1015
  },
1016
+ account: {address: account},
1011
1017
  };
1012
1018
  if (
1013
1019
  newState.step === 'WalletConnected' &&
@@ -1083,6 +1089,7 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
1083
1089
  invalidChainId: alwaysOnChainId != chainId,
1084
1090
  switchingChain: false,
1085
1091
  },
1092
+ account: {address: account},
1086
1093
  };
1087
1094
  if (
1088
1095
  newState.step === 'WalletConnected' &&
@@ -1192,43 +1199,49 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
1192
1199
 
1193
1200
  // ensureConnected overloads - the default step depends on targetStep
1194
1201
  function ensureConnected(
1195
- options?: ConnectionOptions,
1202
+ options?: EnsureConnectedOptions,
1196
1203
  ): Promise<WalletConnected<WalletProviderType> | SignedIn<WalletProviderType>>;
1197
1204
  function ensureConnected(
1198
1205
  step: 'WalletConnected',
1199
- mechanism?: WalletMechanism<string | undefined, `0x${string}` | undefined>,
1200
- options?: ConnectionOptions,
1206
+ mechanismOrOptions?: WalletMechanism<string | undefined, `0x${string}` | undefined> | EnsureConnectedOptions,
1207
+ options?: EnsureConnectedOptions,
1201
1208
  ): Promise<WalletConnected<WalletProviderType>>;
1202
1209
  function ensureConnected(
1203
1210
  step: 'SignedIn',
1204
1211
  mechanism?: Mechanism,
1205
- options?: ConnectionOptions,
1212
+ options?: EnsureConnectedOptions,
1206
1213
  ): Promise<SignedIn<WalletProviderType>>;
1207
1214
  async function ensureConnected<Step extends 'WalletConnected' | 'SignedIn'>(
1208
- stepOrMechanismOrOptions?: Step | Mechanism | ConnectionOptions,
1209
- mechanismOrOptions?: Mechanism | ConnectionOptions,
1210
- options?: ConnectionOptions,
1215
+ stepOrMechanismOrOptions?: Step | Mechanism | EnsureConnectedOptions,
1216
+ mechanismOrOptions?: Mechanism | EnsureConnectedOptions,
1217
+ options?: EnsureConnectedOptions,
1211
1218
  ): Promise<WalletConnected<WalletProviderType> | SignedIn<WalletProviderType>> {
1212
1219
  // Determine if first arg is a step string, mechanism, or options
1213
1220
  let step: 'WalletConnected' | 'SignedIn';
1214
1221
  let mechanism: Mechanism | undefined;
1215
- let opts: ConnectionOptions | undefined;
1222
+ let opts: EnsureConnectedOptions | undefined;
1216
1223
 
1217
1224
  if (typeof stepOrMechanismOrOptions === 'string') {
1218
1225
  // First arg is a step
1219
1226
  step = stepOrMechanismOrOptions as 'WalletConnected' | 'SignedIn';
1220
- mechanism = mechanismOrOptions as Mechanism | undefined;
1221
- 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
+ }
1222
1235
  } else if (stepOrMechanismOrOptions && 'type' in (stepOrMechanismOrOptions as any)) {
1223
1236
  // First arg is a mechanism
1224
1237
  step = targetStep; // Use configured target as default
1225
1238
  mechanism = stepOrMechanismOrOptions as Mechanism;
1226
- opts = mechanismOrOptions as ConnectionOptions | undefined;
1239
+ opts = mechanismOrOptions as EnsureConnectedOptions | undefined;
1227
1240
  } else {
1228
1241
  // First arg is options or undefined
1229
1242
  step = targetStep; // Use configured target as default
1230
1243
  mechanism = undefined;
1231
- opts = stepOrMechanismOrOptions as ConnectionOptions | undefined;
1244
+ opts = stepOrMechanismOrOptions as EnsureConnectedOptions | undefined;
1232
1245
  }
1233
1246
 
1234
1247
  // For WalletConnected step, default to wallet mechanism
@@ -1239,13 +1252,31 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
1239
1252
  const promise = new Promise<WalletConnected<WalletProviderType> | SignedIn<WalletProviderType>>(
1240
1253
  (resolve, reject) => {
1241
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
+
1242
1272
  if (
1243
1273
  $connection.step == 'WalletConnected' &&
1244
1274
  ($connection.wallet.status == 'locked' || $connection.wallet.status === 'disconnected')
1245
1275
  ) {
1246
1276
  forceConnect = true;
1247
1277
  mechanism = $connection.mechanism; // we reuse existing mechanism as we just want to reconnect
1248
- } else if ($connection.step == step) {
1278
+ } else if (canResolve($connection)) {
1279
+ // Only resolve if step matches AND chain is valid (or skipChainCheck)
1249
1280
  resolve($connection as any);
1250
1281
  return;
1251
1282
  }
@@ -1254,14 +1285,16 @@ export function createConnection<WalletProviderType = UnderlyingEthereumProvider
1254
1285
  connect(mechanism, opts);
1255
1286
  }
1256
1287
  const unsubscribe = _store.subscribe((connection) => {
1288
+ // Reject on disconnect/back to Idle
1257
1289
  if (connection.step === 'Idle' && idlePassed) {
1258
1290
  unsubscribe();
1259
- reject();
1291
+ reject(new Error('Connection cancelled'));
1260
1292
  }
1261
1293
  if (!idlePassed && connection.step !== 'Idle') {
1262
1294
  idlePassed = true;
1263
1295
  }
1264
- if (connection.step === step) {
1296
+ // Check full resolution conditions including chain validity
1297
+ if (canResolve(connection)) {
1265
1298
  unsubscribe();
1266
1299
  resolve(connection as any);
1267
1300
  }