Skip to main content

· 3 min read
Ekene Eze

A few months ago we announced the Login with Collab.Land Flow. An effort that allows Collab.Land developers to securely authenticate users and gain access to their Collab.Land resources. By registering a client application through the developer portal, developers can obtain credentials that enable them to interact with the Collab.Land API on behalf of authenticated users.

This has been very well received with many adoption instances and use cases emerging within our online communities. For community administrators, this represents a great opportunity to create online resources exclusively accessible to their community members, all without the need for extensive development work.

The success of this feature and the requests from our developers have led us to an exciting decision: we are now making this functionality available for miniapps as well. This means that miniapp developers can prompt Discord users to grant authorization for accessing their data, such as connected wallets and profiles.

💡 If you've ever envisioned building a miniapp that relies on users granting access to their wallet addresses, this feature now makes it a reality.

How it works

Collab.Land miniapps are built using Collab Actions, which are pre-built templates designed to streamline the miniapp creation process. These templates come with essential functionalities like signature verification built-in. The hello-action example serves as a prime example of how Collab Actions operate.

When you run the Action locally, users can execute a slash command and provide a name as a parameter. The Action sends this provided name to Collab.Land, which processes the request and responds with a greeting.

What we've done to enhance this flow is to introduce an additional step that enables you (the developer) to request user authorization for data access. To implement this feature, we've added two functions behind the scenes: one to request user permission and another to construct the modal for user authorization.

The requestUserPermissions function is responsible for requesting user permission to access their data:

async requestUserPermissions(
request: DiscordActionRequest<APIChatInputApplicationCommandInteraction>,
permissions: string[],
) {
const metadata = await this.getMetadata();
if (metadata.manifest.clientId == null) {
throw new HttpErrors.BadRequest(`Missing clientId in manifest`);
}
const msg = this.buildUserPermissionMessage(
request.id,
metadata.manifest.clientId,
permissions,
);

return this.followupMessage(request, msg);
}

This function takes a DiscordActionRequest object and an array of permissions that you wish to request from the user. It then constructs a message requesting permission and returns it using the followupMessage function.

The second function, buildUserPermissionMessage, creates the modal that solicits user authorization. It takes the request ID, your miniapp's client ID, and an array of permissions you want to request from the user:

buildUserPermissionMessage(
interactionId: string,
clientId: string,
scopes: string[],
) {
const builder = new EmbedBuilder()
.setTitle('Request user permissions')
.addFields(
{
name: ACTION_CLIENT_ID,
value: clientId,
},
{
name: ACTION_REQUESTED_SCOPES,
value: scopes.join(' '),
},
)
.setDescription(
`Action ${clientId} requires the following permissions:\n` +
scopes.map(p => `- **${p}**`).join('\n'),
);
const row =
new ActionRowBuilder<MessageActionRowComponentBuilder>().addComponents(
new ButtonBuilder()
.setCustomId(`${APPROVE_USER_PERMISSIONS}:${interactionId}`)
.setLabel(`Approve`)
.setEmoji({
name: '✅',
})
.setStyle(ButtonStyle.Primary),
new ButtonBuilder()
.setCustomId(`${DENY_USER_PERMISSIONS}:${interactionId}`)
.setLabel(`Deny`)
.setEmoji({
name: '❌',
})
.setStyle(ButtonStyle.Primary),
);
const msg: RESTPostAPIWebhookWithTokenJSONBody = {
embeds: [builder.toJSON()],
components: [row.toJSON()],
};
return msg;
}

The modal contains a message explaining what data you want access to. Once the user grants permission, you can use the Collab.Land API to access their data and build your miniapp accordingly.

All of this functionality is already integrated into the hello-action example repository, ready for you to clone and explore as you see fit. With these recent updates, you can now create miniapps that offer user-specific interactions, access user profiles, connected wallets, and communities.

Get started from the repo here.

· 8 min read
Ekene Eze

Security is a top priority for us here at Collab.Land. We not only ensure the safety of our members and admins but also take great care in securing the connections and data shared by developers through our APIs. One essential aspect of this security is signature verification. Today, we'll explore the importance of signature verification and guide you through the process of implementing it in your Miniapps on Collab.Land.

Why Signature Verification Matters

Imagine sending a valuable package through the mail. To ensure it arrives intact and untampered with, you'd use a sealed envelope. In the digital world, that envelope is a digital signature. It guarantees the authenticity and integrity of your data in an environment where anyone can intercept and manipulate it if not properly secured.

Digital signatures involve two fundamental operations:

  1. Signing: Using a private key to produce a digital signature for raw data.
  2. Verification: Using a public key to confirm the authenticity and integrity of data against the received raw data.

Web2 and Web3 technologies heavily rely on digital signatures to preserve data integrity and protection, but they serve slightly different purposes.

Web2: Data Integrity and Security

In Web2, digital signatures are commonly used to verify data integrity and secure open API endpoints from common denial-of-service attacks. They provide integrity, authentication, and non-repudiation. We see this commonly used in email authentication, WhatsApp, Imessage, etc where a digital signature is used to verify the sender's identity and ensure the data's integrity.

Web3: Everyday Transactions

In Web3, digital signatures are everywhere, they are used for signing transactions, messages, and verifying wallet ownership. For instance, Collab.Land uses your wallet's digital signature to verify your wallet address, ensuring secure connections.

How Digital Signatures Work

Let's look at a simple flow of how digital signatures work between two parties, Alice and Bob:

  1. Alice wants to send data to Bob.
  2. Alice possesses a private key (known only to her) and a public key (visible to anyone).
  3. She signs her message with her private key and sends both the message and the signature to Bob.
  4. Bob, to verify that the message came from Alice, uses her public key to check the signature against the received message.

Digital signatures are particularly crucial when sharing data over the public internet, which can be a daunting place. If you run an exposed API server on the internet, implementing security measures becomes essential. This is where Collab.Land's API and signature verification come into play.

Defending Against DDoS Attacks

One common threat on the internet is Distributed Denial of Service (DDoS) attacks. In these attacks, malicious actors flood a network or server with payloads until it becomes unresponsive. To mitigate these attacks, consider:

  • Rate-limiting API calls
  • Whitelisting or blacklisting IPs
  • Implementing Digital Signature Verification Algorithms
  • Using a Web Application Firewall

Implementing Signature Verification in Miniapps

Now, let's dive into how you can implement signature verification for your Collab.Land Miniapps:

  1. Always check for signature headers in your /interactions endpoint before processing any data.
  2. Verify the signature against Collab.Land's API public key and the received raw data. You can find Collab.Land API public keys at https://api.collab.land/config.
  3. Only trust and process the data when the signature is successfully verified. This ensures that the data was sent by Collab.Land and can be trusted.

Hands-On with Code

To experiment with implementing signature verification, you can use Collab.Land's Miniapp templates. Here's a step-by-step guide:

  1. Clone one of the Collab.Land Miniapp templates.
  2. Review the Editing Response Messages documentation to understand the expected request format.
  3. Open the .env file and set SKIP_VERIFICATION to true.
  4. Build and run the server with npm run build && npm run start.
  5. Follow the documentation to test your Miniapp in a Discord server.
  6. Send a malicious request to the server URL (ACTION URL). You'll notice that the server breaks.

Legitimate requests will fail as well, illustrating the importance of proper verification.

Protecting Your Miniapp

Collab.Land places a strong emphasis on security for miniapp developers. Here's how we ensure security:

  • Collab.Land's API always sends a digital signature in the request headers to the action URLs used by partner Miniapps.
  • We expose public keys that developers can use to verify webhook payloads.
  • We strongly recommend implementing signature verification in production to safeguard against attacks and protect user data.

Updating Your Codebase for Signature Verification

To implement signature verification in your codebase:

  1. Remove the SKIP_VERIFICATION variable or set it to false in the .env file.
  2. Restart the server.
  3. Resend a malicious payload. The API will respond with a denial because the signature verification headers are missing, ensuring that only requests from Collab.Land is accepted and processed.

Implementing Signature Verification in the Code

Collab.Land simplifies signature verification with an easy-to-use verify function. This function pulls in public keys from the /config endpoint for different environments (QA and Production). When a request hits the /interactions endpoint, the verify function runs first, checking verification headers, matching keys, and expiration.

Collab.Land supports two verification algorithms, ECDSA and ED25519, depending on the signature type. Signature verification is already baked into the Collab.Land Miniapp templates and all you need to do to enable it is set the SKIP_VERIFICATION env variable to true. However if you'd like to take a look at our implementation or roll your own, here's a sample code snippet:

Initialize the SignatureVerifier:

  static async initVerifier() {
const apiUrl = `https://api${
process.env.NODE_ENV === "production" ? "" : "-qa"
}.collab.land/config`;
const keysResponse = await fetch(apiUrl);
const keys = await handleFetchResponse<CollabLandConfig>(
keysResponse,
200,
{
customErrorMessage: `Error in fetching collab.land config from URL: ${apiUrl}`,
}
);
SignatureVerifier.ECDSAPublicKey = keys.actionEcdsaPublicKey;
SignatureVerifier.ED25519PublicKey = Buffer.from(
decode(keys.actionEd25519PublicKey)
).toString("hex");
debug("API URL for Collab.Land Config:", apiUrl);
debug("SingatureVerifier Initialized");
}

In the snippet above, we fetch the public keys from the /config endpoint and store them in the SignatureVerifier class. We also decode the ED25519 public key from base64 to hex.

Next, verify the signature:

  verify(req: Request, res: Response) {
if (!process.env.SKIP_VERIFICATION) {
try {
debug("Verifying signature...");
const ecdsaSignature = req.header(ActionEcdsaSignatureHeader);
const ed25519Signature = req.header(ActionEd25519SignatureHeader);
const signatureTimestamp: number = parseInt(
req.header(ActionSignatureTimestampHeader) ?? "0"
);
const body = JSON.stringify(req.body);
const signature = ecdsaSignature ?? ed25519Signature;
if (!signature) {
throw new HttpErrors[401](
`${ActionEcdsaSignatureHeader} or ${ActionEd25519SignatureHeader} header is required`
);
}
const signatureType =
signature === ecdsaSignature ? "ecdsa" : "ed25519";
const publicKey = this.getPublicKey(signatureType);
if (!publicKey) {
throw new HttpErrors[401](`Public key is not set.`);
}
this.verifyRequest(
body,
signatureTimestamp,
signature,
publicKey,
signatureType
);
return true;
} catch (err) {
if (HttpErrors.isHttpError(err)) {
res.status(err.statusCode).json({
message: err.message,
});
return false;
} else {
res.status(403).json({
message: "Unauthorized",
});
return false;
}
}
} else {
return true;
}
}

In the snippet above, we check if the SKIP_VERIFICATION env variable is set to true. If it is, we skip the verification process and return true. Otherwise, we check for the signature headers and verify the signature against the public key. If the signature is valid, we return true, otherwise we return false and send an error response.

Next, we define a function to get the Collab.Land public keys:

 private getPublicKey(signatureType: "ecdsa" | "ed25519") {
return signatureType === "ecdsa"
? SignatureVerifier.ECDSAPublicKey
: SignatureVerifier.ED25519PublicKey;
}

In the snippet above, we return the appropriate public key based on the signature type.

Next, we define a function to verify the signature using the ED25519 algorithm:

private verifyRequestWithEd25519(
publicKey: string,
signature: string,
body: string
) {
let verified = false;
try {
debug("Verifying webhook request with Ed25519 signature...");
debug(
"Public key: %s, signature: %s, message: %s",
publicKey,
signature,
body
);
verified =
signature != null &&
nacl.sign.detached.verify(
Buffer.from(body, "utf-8"),
Buffer.from(signature, "hex"),
Buffer.from(publicKey, "hex")
);
debug("Signature verified: %s", verified);
} catch (err: AnyType) {
verified = false;
debug(err.message);
}

if (!verified) {
throw new HttpErrors[403](
"Invalid request - Ed25519 signature cannot be verified."
);
}
return verified;
}

In the snippet above, we verify the signature using the ED25519 algorithm. We use the nacl library to verify the signature.

Consequently, we define a function to verify the signature using the ECDSA algorithm:

 private verifyRequestWithEcdsa(
publicKey: string,
signature: string,
body: string
) {
let verified = false;
try {
debug("Verifying webhook request with Ecdsa signature...");
debug(
"Public key: %s, signature: %s, message: %s",
publicKey,
signature,
body
);
const digest = utils.hashMessage(body);
verified =
signature != null &&
utils.recoverPublicKey(digest, signature) === publicKey;
debug("Signature verified: %s", verified);
} catch (err) {
debug("Fail to verify signature: %O", err);
verified = false;
}

if (!verified) {
debug("Invalid signature: %s, body: %s", signature, body);
throw new HttpErrors[403](
"Invalid request - Ecdsa signature cannot be verified."
);
}
return verified;
}

Here, we verify the signature using the ECDSA algorithm. We use the ethers library to verify the signature.

Finally, we define a function to verify the request payload:

private verifyRequest(
body: string,
signatureTimestamp: number,
signature: string,
publicKey: string,
signatureType = "ecdsa"
) {
const delta = Math.abs(Date.now() - signatureTimestamp);
if (delta >= 5 * 60 * 1000) {
throw new HttpErrors[403](
"Invalid request - signature timestamp is expired."
);
}
const msg = signatureTimestamp + body;
if (signatureType === "ed25519") {
this.verifyRequestWithEd25519(publicKey, signature, msg);
} else if (signatureType === "ecdsa") {
this.verifyRequestWithEcdsa(publicKey, signature, msg);
}
return JSON.parse(body);
}

In conclusion, implementing signature verification in your Collab.Land Miniapps is crucial for ensuring data security and protecting against potential threats. By following these steps and best practices, you can create a safer and more trustworthy environment for your users while building innovative Miniapps on the Collab.Land Marketplace. Happy coding and stay secure!

· 4 min read
Ekene Eze

Token gating (AKA Token Granted Access) is a concept that has gained significant traction in recent years, particularly within decentralized autonomous organizations (DAOs) and non-fungible token (NFT) communities. At its core, token gating involves using on-chain assets to grant or restrict access to a community or a resource.

The concept of token gating was first popularized by the Collab.Land team, who made it possible for DAOs and other tokenized communities to verify membership through the possession of on-chain assets. A good example of this is how communities like Axie Infinity use Collab.Land to authenticate new users who are joining their community. New members are required to go through a one-time wallet connection flow, after which they will be assigned roles based on their asset holdings. These roles will give them a tailored experience in the community, like access to exclusive messaging permissions, private channels etc.

The success of this approach grew the Collab.Land ecosystem to over 50k communities with a reach of over 100MM. That is huge, but we’re not stopping there! We are moving to the next stage - exposing our infrastructure to developers. What if developers had the ability to gate or grant access to their websites or specific parts of their projects based on the possession of some specified on-chain assets? Well, they can, with our website token gating APIs.

Introducing Collab.Land’s Token Gating APIs

In January, we announced a new /access-control endpoint for token gating that allows developers to control access to their applications based on the possession of specific on-chain tokens. The endpoint accepts two parameters:

  • account - The wallet address of the user.
  • rules - The token gating rules that specify the assets that qualify a user.

For each rule, Collab.Land will return a response indicating whether or not the rule has been granted or denied for the user. Here’s a sample request to the Collab.Land /access-control endpoint:

POST https://api.collab.land/access-control/check-roles
BODY:
{
"account": "0x01c20350ad8..............7bca295",
"rules": [
{
"type": "ERC721",
"chainId": 1,
"minToken": "1",
"contractAddress": "0xbc4ca0edaxxx8a936f13d",
"roleId": "001"
}
]
}

Where: account represents the user's wallet address and rules is an array of objects representing each rule to be checked against the user's wallet. This call would return a sample response like this:

{
"roles": [
{
"id": "001",
"granted": true
}
]
}

With this, developers can build simple and if needed, complex token gating configurations that allow them to offer custom experiences to qualified users. To learn more about the Collab.Land token gating APIs, please read the official documentation or dive into a practical tutorial to build a gated website in minutes. You can also get your hands dirty with the Github repo.

How to Get Started

First, head over to the Collab.Land DevPortal and create a client application. The client app will provide you with the necessary credentials (API Key, secret and client ID) needed to interact with the Collab.Land APIs. With the client app created, you can leverage our token gating tutorial or this video to gain a better understanding of our implementation detail. For instance, if you want to build a token gated website with JavaScript, here’s a sample code snippet to call the Collab.Land /check-roles endpoint using fetch:

const res = await fetch(`https://api.collab.land/access-control/check-roles`, {
method: 'POST',
headers: new Headers({
Accept: 'application/json',
'X-API-KEY': process.env.COLLABLAND_KEY,
'Content-Type': 'application/json',
}),
body: JSON.stringify({
account: myWalletAddr, // pass in the user's wallet address
rules: [{}, {}], // pass in the rules to be checked
}),
});

With our token gating APIs, we are extending the successful access control patterns in our communities and DAOs to developers. With one endpoint, developers can gate and grant access to websites, web applications, games, mobile applications and so on.

I look forward to seeing what you build, and when you do, I’d be happy to amplify it for you. I've also linked a video tutorial on the Getting Started section to show you how to implement this API in a Next.js project specifically.

· 5 min read
Ekene Eze

Read on to learn how TheSuccessFinder team leveraged Collab.Land's APIs to enhance the security and exclusivity of their online communities. This process is even easier now thanks to the launch of the Collab.Land Developer Portal.

Introducing TheSuccessFinder

TheSuccessFinder (TSF) is a community platform designed to foster effective communication, collaboration, and knowledge sharing. With its four main features—leaders, communities, knowledge center, and events—TSF aims to create safe and secure online communities that provide valuable experiences for its users.

TSF empowers leaders to create text and audio communication channels such as announcements, community conversations, courses, and audio rooms with just one click.

The community feature within TSF is a space for synchronous conversations and working together on various projects by posting, replying, and using video collaboration.

The knowledge center within TSF hosts blogs and vlogs. New members can search for leaders based on their interests and connect with them through these knowledge-sharing resources, and also allows them to access educational content and gain insights from leaders in their areas of interest.

Additionally, through events in TSF, leaders offer events to their community. Members can conveniently purchase them with simple payment processing.

TheSuccessFinder commits to creating a safe and secure environment for leaders, while also empowering learners to connect and collaborate effectively.

Early Challenges: Building a Rewarding Community Platform

When developing TSF, the team faced the challenge of finding an existing platform that would facilitate effective collaboration, communication, and knowledge sharing for its users. And so, TSF created a platform that offers the positive aspects of existing platforms while addressing their drawbacks to provide a custom experience for their users.

To start, TSF implemented a Know Your Customer (KYC) process for community leaders. KYC ensured that leaders are competent in the areas they wanted to create communities for, preventing unknowns from diluting the value and authenticity of the platform. TSF used custom authentication solutions to ensure that only authorized users gained access to the appropriate communities, improving member safety. The TSF team sought user feedback to identify and address any loopholes or vulnerabilities encountered during the implementation process.

During the development process, TSF became increasingly aware of web3 technologies and their security benefits. By studying platforms like Discord, Telegram, and Facebook groups, the team realized the potential of integrating web2 and web3 technologies to enhance security and authorization.

Solutions: Leveraging Collab.Land for Enhanced Security and Access Control

During their search for a token gating solution, TSF discovered Collab.Land. Collab.Land appeared to be the perfect fit for their needs. Then, TSF conducted extensive research and reached out to partners familiar with web3 technologies. All signs still pointed to Collab.Land, as they were already working with tens of thousands of communities on Discord and Telegram.

Collab.Land's strong reputation and long track record gave TSF the confidence to pursue an integration. By integrating Collab.Land, TSF gained the ability to token gate and allow community leaders to define access requirements for their members.

“One of the major advantages of integrating with Collab.Land was eliminating workarounds. With token gating, users either have the required token or they don't, which ensures a secure and streamlined access restriction process.” ~ Brandon Straza (Founder, TheSuccessFinder)

Collab.Land provides a complete suite of token gating functionalities that go beyond regular RPC calls to check the balance of a wallet. With their APIs, developers can leverage Collab.Land’s comprehensive and scalable token gating engines to extend their community and project’s gating functionalities beyond the scopes of Discord and Telegram.

The integration was initially intended to only gate access to the communities section, but TSF soon expanded the Collab.Land implementation to other areas of the platform, including the knowledge center. Using Collab.Land, blogs, courses, and video rooms can be token gated, enabling community leaders to easily monetize their content and resources. For example, TSF recently integrated token gating into secure video rooms, allowing leaders to ensure that only users with the necessary tokens can enter video meeting rooms for enhanced security and exclusivity.

Integrating with Collab.Land's Token Gating API

TSF's integration with Collab.Land established a double layer of security for both leaders and learners. The platform has significantly reduced the risk of both fake communities and the dissemination of false information. Now, individuals entering the community are verified before accessing content or engaging, providing tremendous value and confidence for both TSF leaders and learners.

The integration process with Collab.Land presented a steep learning curve for TSF's developers, as they had no prior experience with web3 technologies or token gating systems. However, the intuitive nature of Collab.Land's token gating APIs, coupled with the comprehensive documentation and responsive support from Collab.Land's DevRel team, facilitated a smooth integration process. Whenever clarification or assistance was needed, TSF's developers relied on Collab.Land's DevRel team, who promptly addressed their queries and provided guidance.

Collab.Land also provided a suite of developer tools to facilitate integration and development, some of which were the API reference, documentation, tutorials, guides, and a comprehensive SDK for frontend development.

This process has been simplified by the launch of Collab.Land's Developer Portal where developers self-serve and create their own client-apps, submit miniapps to the marketplace, and leverage the Login with Collab.Land (LWC) flow to activate members.

Looking to the future, TSF believes that token gating technology will continue to play a pivotal role in shaping online experiences. The platform has already adopted token gating in more areas than initially planned. TSF remains committed to an ongoing partnership with Collab.Land and the continued utilization of token gating technology.

Visit the Collab.Land Developer Portal to start building your own integration today!

· 4 min read
Ekene Eze

Collab.Land is proud to announce the launch of its new Developer Portal and API product offering. These pivotal additions serve to broaden accessibility for developers, paving the way for further innovation within the comprehensive Collab.Land network of communities.

Introducing the Developer Portal

The Developer Portal provides a dedicated platform for developers to contribute their Miniapps to:

  • Create client applications and get access to API credentials
  • Contribute Miniapps to the Collab.Land Marketplace.
  • Leverage LWC flow to request user permissions for data access.

This significant evolution enables developers to reach over 50,000 communities who are actively seeking to enhance their members' experiences. Through the dev portal, developers can build and submit miniapps to provide to a vast array of applications and services for community admins to customize their communities.

First Look at Collab.Land APIs

For the first time, the Developer Portal offers developers access to Collab.Land's APIs. These APIs encourage direct interaction with Collab.Land's network, facilitating a seamless integration process for active members across various websites, platforms, or apps.

Tiered API Product Offering

Designed with diverse needs in mind, Collab.Land's API product is available in three tiers.

Free Tier: Ideal for newcomers to the API, offering limited requests and rate limits for initial experimentation and familiarization as well as development.

  • 10 requests per second
  • 10000 requests per month
  • 5 Max marketplace keys
  • 5 Max client apps

Paid Tier: Geared towards developers requiring higher request and rate limits. This tier covers most use cases, perfectly suited for those ready to incorporate the API into larger projects:

  • 15 requests per second
  • 1000000 requests per month
  • 500 Max marketplace keys
  • 500 Max client apps

Enterprise Tier: Customized to suit specific requirements, the Enterprise Plan is for brands or projects that need custom support or integrations demanding additional resources from the core team. For those interested in this plan, please direct all inquiries to the Collab.Land team.

API Use Cases

Build token gated websites and web applications

Build token gated web apps to provide additional functionalities to your community, fans or customers. With the website token gating features, you can gate / grant access to exclusive content and features on your site. Learn more.

Reach 50k+ communities on Collab.Land with miniapps

Build lightweight implementations of your projects that run on the Collab.Land bot as a miniapp. They are a great way to get your project in front of 50k+ community admins and 9M+ users. Learn more

Request user permissions for data access with LWC Flow

Leverage the Collab.Land LWC flow to request user permissions to access their data on Collab.Land. This will allow you to access user wallets and build custom experiences in your projects. The LWC flow follows the OAuth2 protocol, allowing applications to obtain an access token that can be used to interact with the Collab.Land API on behalf of the authenticated user.

Collab.Land remains committed to privacy and security. Accordingly, any use of the community APIs that involves member data will necessitate explicit user consent, reflecting best practices in data privacy and giving members complete control over their personal information.

Empowering the Web3 Journey

At Collab.Land we are dedicated to empowering multiple personas on their journey through web3. By offering developers more extensive access and powerful tools, we are fostering innovation and promoting accessibility within our network. Simultaneously, we stay true to our commitment to safety and privacy. The launch of the Developer Portal and new API product signifies a significant milestone in our ongoing mission to create a more interactive, personalized, and secure digital ecosystem and we can't wait to see what you all build.