Skip to content
Draft
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
6 changes: 6 additions & 0 deletions .changeset/dry-peas-ring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@exactly/server": patch
"@exactly/docs": patch
---

🐛 fix update card webhook schema
5 changes: 5 additions & 0 deletions .changeset/fifty-friends-bet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

🐛 fix webhook logging for text response
5 changes: 5 additions & 0 deletions .changeset/long-moons-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

🐛 fix webhook retries
5 changes: 5 additions & 0 deletions .changeset/loud-shoes-visit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

🐛 fix user webhook routing
5 changes: 5 additions & 0 deletions .changeset/olive-onions-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ add webhook api
5 changes: 5 additions & 0 deletions .changeset/quick-ants-write.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ add transaction receipt to webhook
5 changes: 5 additions & 0 deletions .changeset/shy-foxes-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ forward exchange rate to webhooks
5 changes: 5 additions & 0 deletions .changeset/violet-plums-move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ forward webhooks to source
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"hdpi",
"hexlify",
"hideable",
"hmac",
"hono",
"IBMPlexMono-Medm",
"IERC",
Expand Down
5 changes: 4 additions & 1 deletion docs/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ export default defineConfig({
{ base: "api", schema: "node_modules/@exactly/server/generated/openapi.json", sidebar: { collapsed: false } },
]),
],
sidebar: [{ label: "Docs", items: ["index", "organization-authentication"] }, ...openAPISidebarGroups],
sidebar: [
{ label: "Docs", items: ["index", "organization-authentication", "webhooks"] },
...openAPISidebarGroups,
],
}),
mermaid(),
],
Expand Down
78 changes: 78 additions & 0 deletions docs/src/content/docs/organization-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,81 @@ authClient.siwe
console.error("nonce error", error);
});
```

## Creating a webhook with the authenticated header

```typescript
import { createAuthClient } from "better-auth/client";
import { siweClient, organizationClient } from "better-auth/client/plugins";
import { mnemonicToAccount } from "viem/accounts";
import { optimismSepolia } from "viem/chains";
import { createSiweMessage } from "viem/siwe";

const chainId = optimismSepolia.id;
const baseURL = "http://localhost:3000";
const authClient = createAuthClient({
baseURL,
plugins: [siweClient(), organizationClient()],
});

const owner = mnemonicToAccount("test test test test test test test test test test test test");

authClient.siwe
.nonce({
walletAddress: owner.address,
chainId,
})
.then(async ({ data: nonceResult }) => {
const statement = `i accept exa terms and conditions`;
const nonce = nonceResult?.nonce ?? "";
const message = createSiweMessage({
statement,
resources: ["https://exactly.github.io/exa"],
nonce,
uri: `https://localhost`,
address: owner.address,
chainId,
scheme: "https",
version: "1",
domain: "localhost",
});
const signature = await owner.signMessage({ message });

await authClient.siwe.verify(
{
message,
signature,
walletAddress: owner.address,
chainId,
},
{
onSuccess: async (context) => {
const headers = new Headers();
headers.set("cookie", context.response.headers.get("set-cookie") ?? "");
const webhooks = await authClient.$fetch(`${baseURL}/api/webhook`, {
headers,
});
console.log("webhooks", webhooks);

// only if owner or admin roles for the organization
const newWebhook = await authClient.$fetch(`${baseURL}/api/webhook`, {
headers,
method: "POST",
body: {
name: "foobar",
url: "https://test.com",
},
});
console.log("new webhook", newWebhook);
},
onError: (context) => {
console.log("authorization error", context);
},
},
);
})
.catch((error: unknown) => {
console.error("nonce error", error);
});

```
Loading
Loading