Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/async-create-message.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rainbow-me/rainbowkit': minor
---

feat: support async createMessage in AuthenticationAdapter
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface AuthenticationAdapter<Message> {
nonce: string;
address: Address;
chainId: number;
}) => Message;
}) => Promise<Message> | Message;
verify: (args: { message: Message; signature: string }) => Promise<boolean>;
signOut: () => Promise<void>;
}
Expand Down
6 changes: 5 additions & 1 deletion packages/rainbowkit/src/components/SignIn/SignIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ export function SignIn({
status: 'signing',
}));

const message = authAdapter.createMessage({ address, chainId, nonce });
const message = await authAdapter.createMessage({
address,
chainId,
nonce,
});
let signature: string;

try {
Expand Down
16 changes: 16 additions & 0 deletions site/data/en-US/docs/custom-authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ const authenticationAdapter = createAuthenticationAdapter({
});
```

#### Server-side message creation

For stricter security, `createMessage` also supports returning a `Promise`, allowing you to construct [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361) messages on the server where security-critical fields like `domain`, `nonce`, and `issued-at` timestamps can't be manipulated by clients. See [SIWE documentation](https://docs.siwe.xyz/quickstart/creating-messages#server-side-message-creation) for more details.

```tsx
createMessage: async ({ nonce, address, chainId }) => {
const response = await fetch('/api/siwe/message', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ nonce, address, chainId }),
});

return await response.text();
},
```

#### Providing the authentication state

Assuming your application is already managing the authentication lifecycle in some way, you can pass the current authentication status along with your custom adapter to `RainbowKitAuthenticationProvider`, wrapping your existing `RainbowKitProvider`.
Expand Down