Skip to content

How to support DAO DAO's Apps interface

noah edited this page May 10, 2024 · 22 revisions

In order to become an app in DAO DAO's Apps interface, follow this guide. This allows DAOs to use your app natively right from DAO DAO!

Here is an example of a DAO interacting with Stargaze to trade NFTs:

image

Integration

Iframe wallet connection is powered by the Cosmiframe package.

If you need a logo to display in your wallet connection modal, you can use https://daodao.zone/daodao.svg or https://daodao.zone/daodao.png.

Wallet adapter

The following wallet adapter libraries support Cosmiframe as a wallet option, so if you use one of them, you're already good to go!

Cosmos Kit

Cosmos Kit with @cosmos-kit/core version >= v2.10.0

By default, Cosmos Kit allows DAO DAO's origins. If you want to customize this, override the allowedIframeParentOrigins field of your ChainProvider. The connection is automatically attempted if it detects it's being used within a trusted iframe. You should not have to do anything other than install and set up the package.

Graz

Graz version >= v0.1.15

Make sure to set iframeOptions.allowedIframeParentOrigins in the grazOptions field in your GrazProvider to include https://daodao.zone and https://dao.daodao.zone. The connection is automatically attempted if it detects it's being used within a trusted iframe.

<GrazProvider
  grazOptions={{
    chains,
    iframeOptions: {
      allowedIframeParentOrigins: ["https://daodao.zone", "https://dao.daodao.zone"],
    },
  }}
>
  <Component {...pageProps} />
</GrazProvider>

Manual integration

If you don't use one of the above adapters, you will need to integrate the iframe connection library directly. Cosmiframe includes instructions in its README.

Check out Kujira's 73-line DAO DAO wallet adapter powered by Cosmiframe: https://github.com/Team-Kujira/kujira.js/blob/a0c0cc974b97e2e84a8c22f1ea9eb3947849441f/src/wallets/daoDao.ts

Security

It is very important to trust the outer app, since supporting this functionality opens up the possibility for the outer app to manipulate messages before asking the user to sign them.

At the end of the day, everything still needs to be approved by a wallet, so a malicious app wrapping your app only has so much power, but relying on user intelligence as a line of defense is definitely not a good idea, especially because most users don't have the tools to validate that the smart contract messages they're seeing are correct.

Cosmiframe enforces security by requiring you to specify allowed origins in the constructor on client instantiation (seen in the examples below). Though it's possible to work around this, I urge you not to. I made it slightly harder than just passing in '*' in the constructor, which is the best I can do (and I'm not telling you how 😡). Don't be lazy and risk your user's money.

All requests verify origin on message sending and receiving, which should automatically prevent any messages being sent to or received from an origin you haven't explicitly allowed. If you want to perform an additional security check which also validates that Cosmiframe is in fact listening from one of the allowed origins, you can use isReady from the client.

import { Cosmiframe } from '@dao-dao/cosmiframe'

const client = new Cosmiframe([
  'https://daodao.zone',
  'https://dao.daodao.zone',
])

// If this is true, we know that:
// - The current app is being used in an iframe.
// - The parent window is running Cosmiframe.
// - The parent window is one of the allowed origins above.
const readyAndSafeToUse = await client.isReady()

This code will ask the outer app if it is DAO DAO, to which DAO DAO responds that it is. Only once verifying this should you support a Cosmiframe connection. The wallet adapters automatically implement this security logic.

Auto connect

Ideally your app detects when it's being used within DAO DAO and automatically uses Cosmiframe or connects to the Cosmiframe wallet in your adapter library. Cosmos Kit and Graz do this for you, but if you're using a different wallet adapter, or manually integrating Cosmiframe, you can simply use Cosmiframe's isReady function to check whether or not you should enable Cosmiframe and auto connect:

import { Cosmiframe } from '@dao-dao/cosmiframe'

const cosmiframe = new Cosmiframe([
  'https://daodao.zone',
  'https://dao.daodao.zone',
])

const shouldAutoConnect = await cosmiframe.isReady()
if (shouldAutoConnect) {
  // AUTO CONNECT
}

React example

In a React app, using the security check and auto-connecting to DAO DAO using Cosmiframe will look something like this:

import { Cosmiframe } from '@dao-dao/cosmiframe'

const cosmiframe = new Cosmiframe([
  'https://daodao.zone',
  'https://dao.daodao.zone',
])

useEffect(() => {
  client.isReady().then((shouldAutoConnect) => {
    if (shouldAutoConnect) {
      // AUTO CONNECT
    }
  })
}, [cosmiframe])

Testing

You can test your integration by visiting a DAO on a chain your app supports, visiting the Apps tab, and entering your app's URL in the Custom URL field.

Once you get it working, reach out to us on our Discord to request being added to our Apps library!