Skip to content

Commit

Permalink
Submit Ninji Wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
khiemsoft committed Jan 16, 2024
1 parent e4f1e1a commit 5a0a6c1
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 1 deletion.
3 changes: 3 additions & 0 deletions examples/solid-vite/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
LeapController,
MetamaskInjectiveController,
StationController,
NinjiController,
UnsignedTx,
WalletController,
WalletName,
Expand Down Expand Up @@ -39,6 +40,7 @@ const WALLETS: Record<WalletName, string> = {
[WalletName.LEAP]: "Leap",
[WalletName.COMPASS]: "Compass",
[WalletName.METAMASK_INJECTIVE]: "MetaMask",
[WalletName.NINJI]: "Ninji",
};
const TYPES: Record<WalletType, string> = {
[WalletType.EXTENSION]: "Extension",
Expand All @@ -51,6 +53,7 @@ const CONTROLLERS: Record<string, WalletController> = {
[WalletName.COMPASS]: new CompassController(),
[WalletName.COSMOSTATION]: new CosmostationController(WC_PROJECT_ID),
[WalletName.METAMASK_INJECTIVE]: new MetamaskInjectiveController(),
[WalletName.NINJI]: new NinjiController(),
};

function getRpc(chain: string): string {
Expand Down
1 change: 1 addition & 0 deletions src/wallet/constants/WalletName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export const WalletName = {
COMPASS: "compass",
COSMOSTATION: "cosmostation",
METAMASK_INJECTIVE: "metamask-injective",
NINJI: "ninji",
} as const;
export type WalletName = (typeof WalletName)[keyof typeof WalletName];
1 change: 1 addition & 0 deletions src/wallet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export { LeapController } from "./wallets/leap/LeapController";
export { MetamaskInjectiveController } from "./wallets/metamask-injective/MetamaskInjectiveController";
export { MnemonicWallet } from "./wallets/mnemonic/MnemonicWallet";
export { StationController } from "./wallets/station/StationController";
export { NinjiController } from "./wallets/ninji/NinjiController";
1 change: 1 addition & 0 deletions src/wallet/utils/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export function verifyArbitrary({
case WalletName.COSMOSTATION:
case WalletName.KEPLR:
case WalletName.LEAP:
case WalletName.NINJI:
return verifyADR36(params);
case WalletName.METAMASK_INJECTIVE:
return verifyEIP191(params);
Expand Down
79 changes: 79 additions & 0 deletions src/wallet/wallets/ninji/NinjiController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Secp256k1PubKey } from "cosmes/client";

import { WalletName } from "../../constants/WalletName";
import { WalletType } from "../../constants/WalletType";
import { WalletConnectV1 } from "../../walletconnect/WalletConnectV1";
import { WalletConnectV2 } from "../../walletconnect/WalletConnectV2";
import { ConnectedWallet } from "../ConnectedWallet";
import { ChainInfo, WalletController } from "../WalletController";
import { NinjiExtension } from "./NinjiExtension";

export class NinjiController extends WalletController {
constructor() {
super(WalletName.NINJI);
this.registerAccountChangeHandlers();
}

public async isInstalled(type: WalletType) {
return type === WalletType.EXTENSION ? "ninji" in window : false;
}

protected async connectWalletConnect<T extends string>(
_chains: ChainInfo<T>[]
): Promise<{
wallets: Map<T, ConnectedWallet>;
wc: WalletConnectV1 | WalletConnectV2;
}> {
// Ninji does not support WC yet
throw new Error("WalletConnect not supported");
}

protected async connectExtension<T extends string>(chains: ChainInfo<T>[]) {
const wallets = new Map<T, ConnectedWallet>();
const ext = window.ninji;
if (!ext) {
throw new Error("Ninji extension is not installed");
}
await ext.enable(chains.map(({ chainId }) => chainId));
for (const { chainId, rpc, gasPrice } of Object.values(chains)) {
const { bech32Address, pubKey, isNanoLedger } = await ext.getKey(chainId);
const key = new Secp256k1PubKey({
key: pubKey,
});
wallets.set(
chainId,
new NinjiExtension(
this.id,
ext,
chainId,
key,
bech32Address,
rpc,
gasPrice,
isNanoLedger
)
);
}
return wallets;
}

protected registerAccountChangeHandlers() {
/**
* ! IMPORTANT !
*
* Since Leap also uses the same event key, this causes issues when a user
* has both leap and ninji wallets connected simultaneously. For example,
* a change in Leap's keystore will trigger Ninji to emit this event as
* well, leading to a race condition when `changeAccount` is called.
*
* The Ninji team has been notified to possibly change this event emitted
* to `accountsChanged` instead.
*/

if (typeof window !== "undefined" && window.ninji) {
window.ninji.on("accountsChanged", () =>
this.changeAccount(WalletType.EXTENSION)
);
}
}
}
4 changes: 4 additions & 0 deletions src/wallet/wallets/ninji/NinjiExtension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { LeapExtension } from "../leap/LeapExtension";

// Ninji's API is similar to Leap.
export const NinjiExtension = LeapExtension;
10 changes: 10 additions & 0 deletions src/wallet/wallets/ninji/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Keplr } from "cosmes/registry";

// Type is similar to Keplr
export type Ninji = Keplr & {
on: (event: string, callback: () => void) => void;
};

export type Window = {
ninji?: Ninji | undefined;
};
4 changes: 3 additions & 1 deletion src/wallet/wallets/window.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Window as CosmostationWindow } from "./cosmostation/types";
import { Window as LeapWindow } from "./leap/types";
import { Window as EthereumWindow } from "./metamask-injective/types";
import { Window as StationWindow } from "./station/types";
import { Window as NinjiWindow } from "./ninji/types";

declare global {
interface Window
Expand All @@ -13,5 +14,6 @@ declare global {
StationWindow,
LeapWindow,
CompassWindow,
EthereumWindow {}
EthereumWindow,
NinjiWindow {}
}

0 comments on commit 5a0a6c1

Please sign in to comment.