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