Skip to content

Commit

Permalink
Merge pull request #943 from IntersectMBO/chore/898-wrapper-wrap-up-w…
Browse files Browse the repository at this point in the history
…allet-interface-into-package-and-export-out

chore/898-wrapper-wrap-up-wallet-interface-into-package-and-export-out
  • Loading branch information
Sworzen1 committed May 8, 2024
2 parents d22ca84 + f73e09d commit 27ed3c3
Show file tree
Hide file tree
Showing 8 changed files with 281 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ changes.

## [Unreleased]

- Add wallet connector package [Issue 898](https://github.com/IntersectMBO/govtool/issues/898)
- Change DRep without metadata name from "Sole Voter" to "Direct Voter" [Issue 880](https://github.com/IntersectMBO/govtool/issues/880)
- Inicialize Usersnap into App [Issue 546](https://github.com/IntersectMBO/govtool/issues/546)
- Integrate frontend with metadata validation service [Issue 617](https://github.com/IntersectMBO/govtool/issues/617)
Expand Down
56 changes: 56 additions & 0 deletions govtool/packages/wallet-connector/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Wallet Service

The WalletService.ts file contains the implementation of a wallet service, designed to manage wallet. It includes the enableWallet function responsible for enabling the wallet connection and allows get cip95 functions.

1. Install wallet-connector package.

```sh
yarn add wallet-connector
```

2. Import service from wallet-connector.

```javascript
import { WalletService } from "@wallet-connector";
```

3. Usage - for enable your browser wallet extension.
EXAMPLE:

```javascript
const newWalletAPI = await WalletService.enableWallet("%WALLET_NAME%");
```

# Wallet Provider

WalletProvider component which serves as a React Context Provider to facilitate wallet integration across components.

1. Install wallet-connector package

```sh
yarn add wallet-connector
```

2. Import WalletProvider from wallet-connector and wrap your app.

```javascript
import { WalletProvider } from "@wallet-connector";

<WalletProvider>
<App />
</WalletProvider>;
```

3. Usage

```javascript
import { useWalletContext } from "@wallet-connector";

const {
disconnectWallet,
enableError,
enableWallet,
isEnableLoading,
walletAPI,
} = useWalletContext();
```
63 changes: 63 additions & 0 deletions govtool/packages/wallet-connector/WalletProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { createContext, useContext, useMemo, useState } from "react";

import { WalletService } from "./WalletService";
import {
TWalletAPI,
WalletContextProviderProps,
WalletConnectorErrors,
WalletContextValues,
} from "./types";

const WalletContext = createContext<WalletContextValues | null>(null);

const WalletProvider = ({ children }: WalletContextProviderProps) => {
const [isEnableLoading, setIsEnableLoading] = useState<boolean>(false);
const [enableError, setEnableError] = useState<string | null>(null);
const [walletAPI, setWalletAPI] = useState<TWalletAPI | null>(null);

const enableWallet = async (walletName: string): Promise<void> => {
setEnableError(null);
setIsEnableLoading(true);
try {
const newWalletAPI = await WalletService.enableWallet(walletName);

if (newWalletAPI) setWalletAPI(newWalletAPI);
} catch (e) {
setEnableError(e);
throw e;
} finally {
setIsEnableLoading(false);
}
};

const disableWallet = () => {
setWalletAPI(null);
};

const value = useMemo(
() => ({
disableWallet,
enableError,
enableWallet,
isEnableLoading,
walletAPI,
}),
[disableWallet, enableError, enableWallet, isEnableLoading, walletAPI]
);

return (
<WalletContext.Provider value={value}>{children}</WalletContext.Provider>
);
};

const useWalletContext = (): WalletContextValues => {
const context = useContext(WalletContext);
if (!context)
throw new Error(
WalletConnectorErrors.USE_WALLET_CONTEXT_USED_WITHOUT_PROVIDER
);

return context;
};

export default { useWalletContext, WalletProvider };
37 changes: 37 additions & 0 deletions govtool/packages/wallet-connector/WalletService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { TWalletAPI, WalletConnectorErrors } from "./types";

export namespace WalletService {
export const enableWallet = async (
walletName: string
): Promise<TWalletAPI> => {
try {
if (!window.cardano[walletName].supportedExtensions)
throw new Error(
WalletConnectorErrors.NO_CIP30_SUPPORT.replace(
"%WALLET_NAME%",
walletName
)
);

if (
!window.cardano[walletName].supportedExtensions.some(
(item) => item.cip === 95
)
)
throw new Error(
WalletConnectorErrors.NO_CIP95_SUPPORT.replace(
"%WALLET_NAME%",
walletName
)
);

const walletApi = await window.cardano[walletName].enable({
extensions: [{ cip: 95 }],
});

return walletApi;
} catch (e) {
throw e;
}
};
}
3 changes: 3 additions & 0 deletions govtool/packages/wallet-connector/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./WalletProvider";
export * from "./WalletService";
export * from "./types";
12 changes: 12 additions & 0 deletions govtool/packages/wallet-connector/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "wallet-connector",
"version": "1.0.0",
"main": "index.ts",
"license": "MIT",
"dependencies": {
"react": "^18.3.1"
},
"devDependencies": {
"@types/react": "^18.3.1"
}
}
69 changes: 69 additions & 0 deletions govtool/packages/wallet-connector/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { ReactNode } from "react";

export type WalletContextProviderProps = {
children: ReactNode;
};

export type WalletContextValues = {
disableWallet: () => void;
enableError: string | null;
enableWallet: (walletName: string) => Promise<void>;
isEnableLoading: boolean;
walletAPI: TWalletAPI | null;
};

export type Extension = {
cip: number;
};

export type TWalletAPI = {
cip95: {
getPubDRepKey(): Promise<string>;
getRegisteredPubStakeKeys(): Promise<string[]>;
getUnregisteredPubStakeKeys(): Promise<string[]>;
signData(arg0: any, arg1: any): Promise<any>;
};
experimantal: {
on(arg0: any, arg1: any): any;
off(arg0: any, arg1: any): any;
getCollateral(): any;
};
getBalance(): Promise<string>;
getChangeAddress(): Promise<string>;
getExtensions(): Promise<Extension[]>;
getNetworkId(): Promise<number>;
getRewardAddresses(): Promise<string[]>;
getUnusedAddresses(): Promise<string[]>;
getUsedAddresses(): Promise<string[]>;
getUtxos(): Promise<string[]>;
signData(arg0: any, arg1?: any): Promise<any>;
signTx(arg0: any, arg1?: any): Promise<any>;
submitTx(arg0: any): Promise<any>;
};

export type EnableExtensionPayload = {
extensions: Extension[];
};

export type CardanoBrowserWallet = {
apiVersion: string;
enable(extensions?: EnableExtensionPayload): Promise<TWalletAPI>;
icon: string;
isEnabled(): Promise<boolean>;
name: string;
supportedExtensions: Extension[];
};

declare global {
interface Window {
cardano: {
[key: string]: CardanoBrowserWallet;
};
}
}

export enum WalletConnectorErrors {
NO_CIP30_SUPPORT = "%WALLET_NAME% wallet doesn't support CIP 30 extension.",
NO_CIP95_SUPPORT = "%WALLET_NAME% wallet doesn't support CIP 95 extension.",
USE_WALLET_CONTEXT_USED_WITHOUT_PROVIDER = "useWalletContext must be used in the WalletProvider.",
}
40 changes: 40 additions & 0 deletions govtool/packages/wallet-connector/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


"@types/prop-types@*":
version "15.7.12"
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz"
integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==

"@types/react@^18.3.1":
version "18.3.1"
resolved "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz"
integrity sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==
dependencies:
"@types/prop-types" "*"
csstype "^3.0.2"

csstype@^3.0.2:
version "3.1.3"
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==

"js-tokens@^3.0.0 || ^4.0.0":
version "4.0.0"
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==

loose-envify@^1.1.0:
version "1.4.0"
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"

react@^18.3.1:
version "18.3.1"
resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz"
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
dependencies:
loose-envify "^1.1.0"

0 comments on commit 27ed3c3

Please sign in to comment.