Skip to content

Commit

Permalink
v0.0.10: await login()
Browse files Browse the repository at this point in the history
- New wagmi/view versions
  • Loading branch information
kristoferlund committed Mar 18, 2024
1 parent e7194b4 commit 25da396
Show file tree
Hide file tree
Showing 11 changed files with 12,573 additions and 3,701 deletions.
15,750 changes: 12,258 additions & 3,492 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions packages/ic-use-siwe-identity/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [0.0.10] - 2024-03-18

### Changed

- The `login` function now returns a `Promise` that resolves to the `Identity` of the logged in user. New signature: `login: () => Promise<DelegationIdentity | undefined>`.
- Upgraded wagmi to v2.5.7.
- This introduces TanStack Query as an additional dependency.
- Also, this means the signture for `signMessageStatus` has changed slightly to `signMessageStatus: "error" | "idle" | "pending" | "success"`.
- Upgraded viem to v2.8.4

## [0.0.9] - 2024-03-07

### Changed
Expand Down
25 changes: 18 additions & 7 deletions packages/ic-use-siwe-identity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ In addition to `ic-use-siwe-identity`, these peer dependencies are required:
- `@dfinity/agent`
- `@dfinity/candid`
- `@dfinity/identity`
- `@tanstack/query`

```bash
npm install ic-use-siwe-identity wagmi viem @dfinity/agent @dfinity/candid @dfinity/identity
Expand All @@ -56,25 +57,35 @@ To use `ic-use-siwe-identity` in your React application, follow these steps:

### 1. Add an Ethereum wallet provider

Before interacting with the useSiweIdentity hook, you need to add an Ethereum wallet provider to your application. The easiest way to do this is by using the [wagmi](https://wagmi.sh) library. Wagmi provides a React hook for connecting to Ethereum wallets, and is used internally by `ic-use-siwe-identity`. We also recommend adding [RainbowKit](https://www.rainbowkit.com/) to handle the wallet connection UI.
Before interacting with the useSiweIdentity hook, you need to add an Ethereum wallet provider to your application. The easiest way to do this is by using the [wagmi](https://wagmi.sh) library. Wagmi provides a React hook for connecting to Ethereum wallets, and is used internally by `ic-use-siwe-identity`. In addition to the wallet provider, wagmi requires you to add TanStack `QueryClientProvider` to your application that handles the async requests that are made when interacting with the Ethereum wallet.

We also recommend adding [RainbowKit](https://www.rainbowkit.com/) to handle the wallet connection UI.

```jsx
// main.tsx

const queryClient = new QueryClient();

ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<WagmiConfig config={wagmiConfig}>
<RainbowKitProvider>
// ...your app
</RainbowKitProvider>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>
// ...your app
</RainbowKitProvider>
</QueryClientProvider>
</WagmiConfig>
</React.StrictMode>
);
```

> [!TIP]
> Check the [wagmi](https://wagmi.sh) and [RainbowKit](https://www.rainbowkit.com) documentation for the most up-to-date setup instructions.

### 2. Setup the `SiweIdentityProvider` component

Wrap your application's root component with `SiweIdentityProvider` to provide all child components access to the SIWE identity context. Provide the component with the `_SERVICPE` type argument, where `_SERVICPE` represents the canister service definition of a canister that implements the [SIWE login interface](src/service.interface.ts). This could be a canister that you have created yourself, using the [ic_siwe](https://github.com/kristoferlund/ic-siwe/tree/main/packages/ic_siwe) library, or the prebuilt [ic_siwe_provider](https://github.com/kristoferlund/ic-siwe/tree/main/packages/ic_siwe_provider) canister. Adding the provider canister to your project as a dependency is the easiest way to get started.
Wrap your application's root component with `SiweIdentityProvider` to provide all child components access to the SIWE identity context. Provide the component with the `_SERVICE` type argument, where `_SERVICE` represents the canister service definition of a canister that implements the [SIWE login interface](src/service.interface.ts). This could be a canister that you have created yourself, using the [ic_siwe](https://github.com/kristoferlund/ic-siwe/tree/main/packages/ic_siwe) library, or the prebuilt [ic_siwe_provider](https://github.com/kristoferlund/ic-siwe/tree/main/packages/ic_siwe_provider) canister. Adding the provider canister to your project as a dependency is the easiest way to get started.

```jsx
// App.tsx
Expand Down Expand Up @@ -182,7 +193,7 @@ export type SiweIdentityContextType = {
prepareLoginError?: Error;

/** Initiates the login process by requesting a SIWE message from the backend. */
login: () => void;
login: () => Promise<DelegationIdentity | undefined>;

/** "error" | "success" | "idle" | "logging-in" - Reflects the current status of the login process. */
loginStatus: LoginStatus;
Expand All @@ -192,7 +203,7 @@ export type SiweIdentityContextType = {

/** Status of the SIWE message signing process. This is a re-export of the Wagmi
* signMessage / status type. */
signMessageStatus: "error" | "loading" | "success" | "idle";
signMessageStatus: "error" | "idle" | "pending" | "success"

/** Error that occurred during the SIWE message signing process. This is a re-export of the
* Wagmi signMessage / error type. */
Expand Down
1 change: 1 addition & 0 deletions packages/ic-use-siwe-identity/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ esbuild.build({
"@dfinity/agent",
"@dfinity/candid",
"@dfinity/identity",
"@tanstack/react-query",
],
plugins: [],
});
14 changes: 8 additions & 6 deletions packages/ic-use-siwe-identity/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ic-use-siwe-identity",
"version": "0.0.9",
"version": "0.0.10",
"description": "React hook and context provider for easy frontend integration with SIWE enabled Internet Computer canisters.",
"author": "Kristofer Lund <[email protected]>",
"repository": {
Expand Down Expand Up @@ -33,11 +33,12 @@
},
"peerDependencies": {
"react": ">=18.0.0",
"viem": ">=1.19.8",
"wagmi": ">=1.4.7",
"viem": ">=2.8.4",
"wagmi": ">=2.5.7",
"@dfinity/agent": ">=1.0.1",
"@dfinity/candid": ">=1.0.1",
"@dfinity/identity": ">=1.0.1"
"@dfinity/identity": ">=1.0.1",
"@tanstack/react-query": ">=5.28.4"
},
"devDependencies": {
"@types/node": "^20.10.6",
Expand All @@ -52,7 +53,8 @@
"npm-run-all": "^4.1.5",
"react": "^18.2.0",
"typescript": "^5.2.2",
"viem": "^1.19.8",
"wagmi": "^1.4.7"
"viem": "^2.8.4",
"wagmi": "^2.5.7",
"@tanstack/react-query": "^5.28.4"
}
}
6 changes: 3 additions & 3 deletions packages/ic-use-siwe-identity/src/context.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ export type SiweIdentityContextType = {
prepareLoginError?: Error;

/** Initiates the login process by requesting a SIWE message from the backend. */
login: () => void;
login: () => Promise<DelegationIdentity | undefined>;

/** "error" | "success" | "idle" | "logging-in" - Reflects the current status of the login process. */
/** "error" | "idle" | "pending" | "success" - Reflects the current status of the login process. */
loginStatus: LoginStatus;

/** `loginStatus === "logging-in"` */
Expand All @@ -51,7 +51,7 @@ export type SiweIdentityContextType = {

/** Status of the SIWE message signing process. This is a re-export of the Wagmi
* signMessage / status type. */
signMessageStatus: "error" | "loading" | "success" | "idle";
signMessageStatus: "error" | "idle" | "pending" | "success";

/** Error that occurred during the SIWE message signing process. This is a re-export of the
* Wagmi signMessage / error type. */
Expand Down
48 changes: 48 additions & 0 deletions packages/ic-use-siwe-identity/src/delegation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { DerEncodedPublicKey, Signature } from "@dfinity/agent";
import type { PublicKey } from "./service.interface";
import { Principal } from "@dfinity/principal";
import { Delegation } from "@dfinity/identity";
import { DelegationChain, type SignedDelegation } from "@dfinity/identity";
import type { SignedDelegation as ServiceSignedDelegation } from "./service.interface";

/**
* Converts a Uint8Array or number array to a Signature object.
*/
export function asSignature(signature: Uint8Array | number[]): Signature {
const arrayBuffer: ArrayBuffer = (signature as Uint8Array).buffer;
const s: Signature = arrayBuffer as Signature;
s.__signature__ = undefined;
return s;
}

/**
* Converts a Uint8Array or number array to a DerEncodedPublicKey object.
*/
export function asDerEncodedPublicKey(
publicKey: Uint8Array | number[]
): DerEncodedPublicKey {
const arrayBuffer: ArrayBuffer = (publicKey as Uint8Array).buffer;
const pk: DerEncodedPublicKey = arrayBuffer as DerEncodedPublicKey;
pk.__derEncodedPublicKey__ = undefined;
return pk;
}

export function createDelegationChain(
signedDelegation: ServiceSignedDelegation,
publicKey: PublicKey
) {
const delegations: SignedDelegation[] = [
{
delegation: new Delegation(
(signedDelegation.delegation.pubkey as Uint8Array).buffer,
signedDelegation.delegation.expiration,
signedDelegation.delegation.targets[0] as Principal[]
),
signature: asSignature(signedDelegation.signature),
},
];
return DelegationChain.fromDelegations(
delegations,
asDerEncodedPublicKey(publicKey)
);
}
5 changes: 5 additions & 0 deletions packages/ic-use-siwe-identity/src/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function normalizeError(error: Error | unknown): Error {
return error instanceof Error
? error
: new Error("An unknown error occurred.");
}
Loading

0 comments on commit 25da396

Please sign in to comment.