Skip to content

Commit

Permalink
feat(wallet-mimir): mimir wallet integration
Browse files Browse the repository at this point in the history
  • Loading branch information
tien committed Feb 24, 2025
1 parent 6606324 commit 6ecc97f
Show file tree
Hide file tree
Showing 19 changed files with 519 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .changeset/loose-lemons-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@reactive-dot/wallet-mimir": minor
---

Added Mimir wallet integration.
10 changes: 9 additions & 1 deletion apps/docs/react/getting-started/connect-wallets.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,27 @@ npm install @reactive-dot/wallet-walletconnect
npm install @reactive-dot/wallet-ledger
```

### [Mimir](https://mimir.global/)

```bash npm2yarn
npm install @reactive-dot/wallet-mimir
```

## Add wallets to the config

```ts title="config.ts"
import { defineConfig } from "@reactive-dot/core";
import { InjectedWalletProvider } from "@reactive-dot/core/wallets.js";
import { LedgerWallet } from "@reactive-dot/wallet-ledger";
import { MimirWalletProvider } from "@reactive-dot/wallet-mimir";
import { WalletConnect } from "@reactive-dot/wallet-walletconnect";

export const config = defineConfig({
// ...
wallets: [
new InjectedWalletProvider(),
new LedgerWalet(),
new LedgerWallet(),
new MimirWalletProvider(),
new WalletConnect({
projectId: "WALLET_CONNECT_PROJECT_ID",
providerOptions: {
Expand Down
10 changes: 9 additions & 1 deletion apps/docs/vue/getting-started/connect-wallets.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,27 @@ npm install @reactive-dot/wallet-walletconnect
npm install @reactive-dot/wallet-ledger
```

### [Mimir](https://mimir.global/)

```bash npm2yarn
npm install @reactive-dot/wallet-mimir
```

## Add wallets to the config

```ts title="config.ts"
import { defineConfig } from "@reactive-dot/core";
import { InjectedWalletProvider } from "@reactive-dot/core/wallets.js";
import { LedgerWallet } from "@reactive-dot/wallet-ledger";
import { MimirWalletProvider } from "@reactive-dot/wallet-mimir";
import { WalletConnect } from "@reactive-dot/wallet-walletconnect";

export const config = defineConfig({
// ...
wallets: [
new InjectedWalletProvider(),
new LedgerWalet(),
new LedgerWallet(),
new MimirWalletProvider(),
new WalletConnect({
projectId: "WALLET_CONNECT_PROJECT_ID",
providerOptions: {
Expand Down
1 change: 1 addition & 0 deletions examples/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@polkadot-api/descriptors": "portal:.papi/descriptors",
"@reactive-dot/react": "workspace:^",
"@reactive-dot/wallet-ledger": "workspace:^",
"@reactive-dot/wallet-mimir": "workspace:^",
"@reactive-dot/wallet-walletconnect": "workspace:^",
"date-fns": "^4.1.0",
"jotai-devtools": "^0.11.0",
Expand Down
2 changes: 2 additions & 0 deletions examples/react/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { defineConfig } from "@reactive-dot/core";
import { createLightClientProvider } from "@reactive-dot/core/providers/light-client.js";
import { InjectedWalletProvider } from "@reactive-dot/core/wallets.js";
import { LedgerWallet } from "@reactive-dot/wallet-ledger";
import { MimirWalletProvider } from "@reactive-dot/wallet-mimir";
import { WalletConnect } from "@reactive-dot/wallet-walletconnect";

const lightClientProvider = createLightClientProvider();
Expand Down Expand Up @@ -55,6 +56,7 @@ export const config = defineConfig({
targetChains: ["polkadot", "kusama", "westend"],
wallets: [
new InjectedWalletProvider({ originName: "ReactiveDOT React Example" }),
new MimirWalletProvider({ originName: "ReactiveDOT React Example" }),
new LedgerWallet(),
new WalletConnect({
projectId: "68f5b7e972a51cf379b127f51a791c34",
Expand Down
2 changes: 1 addition & 1 deletion nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
"cache": true
}
},
"parallel": 9
"parallel": 10
}
33 changes: 16 additions & 17 deletions packages/core/src/wallets/injected/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
type InjectedExtension,
type InjectedPolkadotAccount,
} from "polkadot-api/pjs-signer";
import { BehaviorSubject, Observable } from "rxjs";
import { BehaviorSubject, Observable, of } from "rxjs";
import { map, switchMap } from "rxjs/operators";

export type InjectedWalletOptions = WalletOptions & { originName?: string };
Expand All @@ -33,7 +33,7 @@ export class InjectedWallet extends Wallet<InjectedWalletOptions, "connected"> {
}
}

connected$ = this.#extension$.pipe(
readonly connected$ = this.#extension$.pipe(
map((extension) => extension !== undefined),
);

Expand All @@ -53,21 +53,20 @@ export class InjectedWallet extends Wallet<InjectedWalletOptions, "connected"> {
}

readonly accounts$ = this.#extension$.pipe(
switchMap(
(extension) =>
new Observable<PolkadotSignerAccount[]>((subscriber) => {
if (extension === undefined) {
subscriber.next([]);
} else {
subscriber.next(this.#withIds(extension.getAccounts()));
subscriber.add(
extension.subscribe((accounts) =>
subscriber.next(this.#withIds(accounts)),
),
);
}
}),
),
switchMap((extension) => {
if (extension === undefined) {
return of([]);
}

return new Observable<PolkadotSignerAccount[]>((subscriber) => {
subscriber.next(this.#withIds(extension.getAccounts()));
subscriber.add(
extension.subscribe((accounts) =>
subscriber.next(this.#withIds(accounts)),
),
);
});
}),
);

override getAccounts() {
Expand Down
1 change: 1 addition & 0 deletions packages/wallet-mimir/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build
4 changes: 4 additions & 0 deletions packages/wallet-mimir/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import recommended from "@reactive-dot/eslint-config";
import tseslint from "typescript-eslint";

export default tseslint.config(...recommended);
47 changes: 47 additions & 0 deletions packages/wallet-mimir/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@reactive-dot/wallet-mimir",
"version": "0.0.0",
"description": "Mimir adapter for Reactive DOT",
"keywords": [
"substrate",
"polkadot",
"mimir"
],
"homepage": "https://reactivedot.dev/",
"bugs": {
"url": "https://github.com/tien/reactive-dot/issues",
"email": "tien.nguyenkhac@icloud.com"
},
"license": "LGPL-3.0-or-later",
"author": "Tiến Nguyễn Khắc <tien.nguyenkhac@icloud.com> (https://tien.zone/)",
"repository": {
"type": "git",
"url": "https://github.com/tien/reactive-dot.git",
"directory": "packages/wallet-mimir"
},
"type": "module",
"files": [
"src",
"build"
],
"exports": "./build/index.js",
"scripts": {
"dev": "tsc --build --watch",
"build": "rm -rf build && tsc --build",
"lint": "eslint src",
"test": "vitest"
},
"dependencies": {
"@mimirdev/apps-inject": "^3.1.1",
"@mimirdev/papi-signer": "^3.1.0",
"@reactive-dot/core": "workspace:^"
},
"devDependencies": {
"@reactive-dot/eslint-config": "workspace:^",
"@tsconfig/recommended": "^1.0.8",
"@tsconfig/strictest": "^2.0.5",
"eslint": "^9.21.0",
"typescript": "^5.7.3",
"vitest": "^3.0.6"
}
}
10 changes: 10 additions & 0 deletions packages/wallet-mimir/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as exports from "./index.js";
import { expect, it } from "vitest";

it("should match inline snapshot", () =>
expect(Object.keys(exports)).toMatchInlineSnapshot(`
[
"MimirWalletProvider",
"MimirWallet",
]
`));
2 changes: 2 additions & 0 deletions packages/wallet-mimir/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { MimirWalletProvider } from "./mimir-wallet-provider.js";
export { MimirWallet } from "./mimir-wallet.js";
33 changes: 33 additions & 0 deletions packages/wallet-mimir/src/mimir-wallet-provider.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { MimirWalletProvider } from "./mimir-wallet-provider.js";
import { MimirWallet } from "./mimir-wallet.js";
import { isMimirReady } from "@mimirdev/apps-inject";
import { describe, it, expect, vi, beforeEach } from "vitest";

vi.mock("@mimirdev/apps-inject");
vi.mock("./mimir-wallet.js");

let provider: MimirWalletProvider;

beforeEach(() => {
provider = new MimirWalletProvider();

vi.clearAllMocks();
});

describe("getWallets", () => {
it("should return empty array when Mimir is not ready", async () => {
vi.mocked(isMimirReady).mockResolvedValue(null);
const wallets = await provider.getWallets();

expect(wallets).toEqual([]);
expect(isMimirReady).toHaveBeenCalled();
});

it("should return MimirWallet instance when Mimir is ready", async () => {
vi.mocked(isMimirReady).mockResolvedValue("origin");
const wallets = await provider.getWallets();

expect(wallets).toHaveLength(1);
expect(wallets[0]).toBeInstanceOf(MimirWallet);
});
});
19 changes: 19 additions & 0 deletions packages/wallet-mimir/src/mimir-wallet-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MimirWallet, type MimirWalletOptions } from "./mimir-wallet.js";
import { isMimirReady } from "@mimirdev/apps-inject";
import { WalletProvider } from "@reactive-dot/core/wallets.js";

export class MimirWalletProvider extends WalletProvider {
constructor(private readonly options?: MimirWalletOptions) {
super();
}

async getWallets() {
const origin = await isMimirReady();

if (origin === null) {
return [];
}

return [new MimirWallet(this.options)];
}
}
Loading

0 comments on commit 6ecc97f

Please sign in to comment.