From e3f9068c09c993260adf014f6dfbe1d941f12008 Mon Sep 17 00:00:00 2001
From: Han <56923450+waddaboo@users.noreply.github.com>
Date: Thu, 5 Dec 2024 19:45:53 +0800
Subject: [PATCH 1/3] docs(tutorial): add on-chain invites tutorial
---
.../docs/tutorials/api-sdk/onchain-invites.md | 172 ++++++++++++++++++
1 file changed, 172 insertions(+)
create mode 100644 apps/docs/docs/tutorials/api-sdk/onchain-invites.md
diff --git a/apps/docs/docs/tutorials/api-sdk/onchain-invites.md b/apps/docs/docs/tutorials/api-sdk/onchain-invites.md
new file mode 100644
index 00000000..e5ff8bd5
--- /dev/null
+++ b/apps/docs/docs/tutorials/api-sdk/onchain-invites.md
@@ -0,0 +1,172 @@
+---
+sidebar_position: 2
+title: On-chain invites
+---
+
+import Tabs from "@theme/Tabs"
+import TabItem from "@theme/TabItem"
+
+# Using invite codes with on-chain groups
+
+This tutorial will guide you through the complete process of adding a user to an on-chain group via invite codes.
+
+## Install library
+
+
+
+
+```bash
+npm install @bandada/utils
+```
+
+
+
+
+```bash
+yarn add @bandada/utils
+```
+
+
+
+
+```bash
+pnpm add @bandada/utils
+```
+
+
+
+
+## Create a new instance
+
+After installing the utils package, create a new instance of `Semaphore`.
+
+More details on the utils package can be found [here](https://github.com/bandada-infra/bandada/tree/main/libs/utils).
+
+- Create a new instance of Semaphore contract.
+
+```ts
+import { getSemaphoreContract } from "@bandada/utils"
+
+const semaphore = getSemaphoreContract("sepolia")
+```
+
+- Create a new instance of Semaphore contract with signer.
+
+```ts
+import { getSemaphoreContract } from "@bandada/utils"
+import { useSigner } from "wagmi"
+
+const { data: signer } = useSigner()
+
+const semaphore = getSemaphoreContract("sepolia", signer)
+```
+
+You can choose to use other signer package of your choice, wagmi is just an example.
+
+
+## Create a group
+
+Create a new on-chain group with associated group.
+
+```ts
+const semaphore = getSemaphoreContract("sepolia", signer as any)
+const admin = await signer.getAddress()
+
+// create on-chain group
+const receipt = await semaphore.createGroup(admin)
+
+const groupIdBigNumber = receipt.events?.[0]?.args?.[0].toString()
+const onchainGroupId = groupIdBigNumber.toString()
+
+const apiKey = "your-api-key"
+const groupCreationDetails = {
+ name: onchainGroupId,
+ description: `This group is associated to the on-chain group ${onchainGroupId}`,
+ treeDepth: 16,
+ fingerprintDuration: 3600
+}
+
+// create associated group
+const group = apiSdk.createGroup(groupCreationDetails, apiKey)
+```
+
+## Add members to on-chain group using invite code
+
+Create a new group invite.
+
+```ts
+const groupId = "your-associated-group-id"
+const apiKey = "your-api-key"
+
+const invite = await apiSdk.createInvite(groupId, apiKey)
+```
+
+## Add member using an invite code
+
+Adds a member to an on-chain group using an invite code.
+
+```ts
+const groupId = "your-group-id"
+const memberId = "member-id"
+const inviteCode = "INVITECODE"
+
+const group = await semaphore.getGroup(groupId, {
+ members: true
+})
+
+const invite = await apiSdk.getInvite(inviteCode)
+
+await semaphore.addMember(group.id, memberId)
+await apiSdk.redeemInvite(inviteCode, invite.group.id)
+```
+
+## Full example
+
+This is an example of how the whole code would look like:
+
+```ts
+import { getSemaphoreContract } from "@bandada/utils"
+import { ApiSdk, SupportedUrl } from "@bandada/api-sdk"
+import { useSigner } from "wagmi"
+
+const apiSdk = new ApiSdk(SupportedUrl.DEV)
+const semaphore = getSemaphoreContract("sepolia", signer as any)
+const { data: signer } = useSigner()
+
+const admin = await signer.getAddress()
+
+// create on-chain group
+const receipt = await semaphore.createGroup(admin)
+
+const groupIdBigNumber = receipt.events?.[0]?.args?.[0].toString()
+const onchainGroupId = groupIdBigNumber.toString()
+
+const apiKey = "your-api-key"
+const memberId = "member-id-1"
+
+const groupCreationDetails = {
+ name: onchainGroupId,
+ description: `This group is associated to the on-chain group ${onchainGroupId}`,
+ treeDepth: 16,
+ fingerprintDuration: 3600
+}
+
+// create associated group
+const associatedGroup = apiSdk.createGroup(groupCreationDetails, apiKey)
+
+// generate invite code with the associated group id
+const invite = await apiSdk.createInvite(associatedGroup.id, apiKey)
+
+// add member to on-chain group
+await semaphore.addMember(onchainGroupId, memberId)
+
+// redeem the invite code after successfully adding the member to the on-chain group
+await apiSdk.redeemInvite(invite.code, associatedGroup.id)
+```
\ No newline at end of file
From fba79cbc59db65d1a19bc8e3f937f5aad1fc8acc Mon Sep 17 00:00:00 2001
From: Han <56923450+waddaboo@users.noreply.github.com>
Date: Thu, 5 Dec 2024 19:46:17 +0800
Subject: [PATCH 2/3] docs(tutorial): add import to full example
---
apps/docs/docs/tutorials/api-sdk/groups.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/apps/docs/docs/tutorials/api-sdk/groups.md b/apps/docs/docs/tutorials/api-sdk/groups.md
index cfe1871e..181b9384 100644
--- a/apps/docs/docs/tutorials/api-sdk/groups.md
+++ b/apps/docs/docs/tutorials/api-sdk/groups.md
@@ -217,6 +217,10 @@ await apiSdk.addMemberByInviteCode(groupId, memberId, inviteCode)
This is an example of how the whole code would look like:
```ts
+import { ApiSdk, SupportedUrl } from "@bandada/api-sdk"
+
+const apiSdk = new ApiSdk(SupportedUrl.DEV)
+
const groupId = "your-group-id"
const memberId = "member-id-1"
const apiKey = "your-api-key"
From e7ebb69762e04822dbc4fd3699925187cd9ce23a Mon Sep 17 00:00:00 2001
From: Vivian Plasencia
Date: Thu, 5 Dec 2024 18:17:13 +0100
Subject: [PATCH 3/3] docs(docs): check if the code has been redeemed
---
.../docs/tutorials/api-sdk/onchain-invites.md | 25 +++++++++++++------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/apps/docs/docs/tutorials/api-sdk/onchain-invites.md b/apps/docs/docs/tutorials/api-sdk/onchain-invites.md
index e5ff8bd5..feff398a 100644
--- a/apps/docs/docs/tutorials/api-sdk/onchain-invites.md
+++ b/apps/docs/docs/tutorials/api-sdk/onchain-invites.md
@@ -1,6 +1,6 @@
---
sidebar_position: 2
-title: On-chain invites
+title: On-chain group invites
---
import Tabs from "@theme/Tabs"
@@ -122,9 +122,15 @@ const group = await semaphore.getGroup(groupId, {
})
const invite = await apiSdk.getInvite(inviteCode)
+const apiKey = "your-api-key"
-await semaphore.addMember(group.id, memberId)
-await apiSdk.redeemInvite(inviteCode, invite.group.id)
+if(invite.isRedeemed) {
+ throw new Error(`Invite code '${inviteCode}' has already been redeemed`)
+} else {
+ await semaphore.addMember(group.id, memberId)
+
+ await apiSdk.redeemInvite(inviteCode, invite.group.id, apiKey)
+}
```
## Full example
@@ -164,9 +170,14 @@ const associatedGroup = apiSdk.createGroup(groupCreationDetails, apiKey)
// generate invite code with the associated group id
const invite = await apiSdk.createInvite(associatedGroup.id, apiKey)
-// add member to on-chain group
-await semaphore.addMember(onchainGroupId, memberId)
+// check if the invite code has been redeemed
+if(invite.isRedeemed) {
+ throw new Error(`Invite code '${invite.code}' has already been redeemed`)
+} else {
+ // add member to on-chain group
+ await semaphore.addMember(onchainGroupId, memberId)
-// redeem the invite code after successfully adding the member to the on-chain group
-await apiSdk.redeemInvite(invite.code, associatedGroup.id)
+ // redeem the invite code after successfully adding the member to the on-chain group
+ await apiSdk.redeemInvite(invite.code, associatedGroup.id, apiKey)
+}
```
\ No newline at end of file