Skip to content

Commit

Permalink
refactor: split connection process of deep link wallets into 2 steps
Browse files Browse the repository at this point in the history
So that application can decide to role their own solution if they don't like the default modal
  • Loading branch information
tien committed Jun 17, 2024
1 parent e51d01c commit bb55469
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
18 changes: 18 additions & 0 deletions packages/core/src/wallets/deep-link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Wallet from "./wallet.js";

type ConnectionHandshake<T> = {
uri: string;
wait: () => Promise<T>;
};

export default abstract class DeepLinkWallet<
THandshakeResponse,
> extends Wallet {
abstract readonly initiateConnectionHandshake: () =>
| ConnectionHandshake<THandshakeResponse>
| Promise<ConnectionHandshake<THandshakeResponse>>;

abstract readonly completeConnectionHandshake: (
response: THandshakeResponse,
) => void | Promise<void>;
}
39 changes: 34 additions & 5 deletions packages/core/src/wallets/wallet-connect/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ReDotError } from "../../errors.js";
import Wallet from "../wallet.js";
import DeepLinkWallet from "../deep-link.js";
import { getPolkadotSignerFromPjs } from "./from-pjs-account.js";
import "@polkadot-api/pjs-signer";
import { AccountId } from "@polkadot-api/substrate-bindings";
Expand All @@ -16,7 +16,7 @@ import { InjectedPolkadotAccount } from "polkadot-api/pjs-signer";
import { BehaviorSubject, lastValueFrom } from "rxjs";
import { map } from "rxjs/operators";

export default class WalletConnect extends Wallet {
export default class WalletConnect extends DeepLinkWallet<SessionTypes.Struct> {
readonly #providerOptions: UniversalProviderOpts;

#provider: IUniversalProvider | undefined;
Expand Down Expand Up @@ -76,7 +76,7 @@ export default class WalletConnect extends Wallet {
map((session) => session !== undefined),
);

override readonly connect = async () => {
override readonly initiateConnectionHandshake = async () => {
await this.initialize();

if (this.#provider?.client === undefined) {
Expand Down Expand Up @@ -107,14 +107,43 @@ export default class WalletConnect extends Wallet {
await this.#provider.client.connect(connectOptions);

if (uri === undefined) {
throw new ReDotError("Client connection doesn't return any URI");
throw new ReDotError("No URI provided by connection");
}

return {
uri,
wait: approval,
};
};

override completeConnectionHandshake = (response: SessionTypes.Struct) =>
this.#session.next(response);

override readonly connect = async () => {
const { uri, wait } = await this.initiateConnectionHandshake();

const modal = await this.#getModal();

await modal.openModal({ uri });

this.#session.next(await approval());
const modalClosePromise = new Promise<void>((resolve) => {
const unsubscribe = modal.subscribeModal((modalState) => {
if (!modalState.open) {
resolve();
unsubscribe();
}
});
});

const sessionPromise = wait();

const session = await Promise.race([sessionPromise, modalClosePromise]);

if (session === undefined) {
throw new ReDotError("Modal was closed");
}

this.completeConnectionHandshake(session);

modal.closeModal();
};
Expand Down

0 comments on commit bb55469

Please sign in to comment.