Portals

Portals Technical Overview

Introduction

  • The Portal specification enables the creation of authenticated experiences on Kade, embeddable as mini dApps on Kade clients.

  • Portals are an extension of The OpenGraph Protocol, similar to how website links load in applications like Twitter.

  • As an extension, the data describing a Portal to be rendered by a client exists as <meta> tags in an HTML page.

Portal Lifecycle

  • Portals begin with an initial Portal Screen, featuring an image, 1-4 buttons, and optionally an input field. Content on this screen should be static.

Response Portals

  • User interactions with the initial and subsequent Portals trigger a POST request to the Portal server with a Portal Packet for authentication. The server returns a 302 redirect response with a Location header to the next Portal.

  • Data on subsequent Portals can be dynamic, displaying user-specific content (e.g., Kade username).

  • The Portal server manages state storage between user interactions.

Example: Aptos Pizzaria

https://x.com/0xkade/status/1795771744839434451

  • The example Portal above illustrates an on-chain Pizza shop:

    1. Users view different pizzas available.

    2. Users enter their desired pizza in an input field.

    3. Users confirm their order and mint the pizza as an NFT, which includes their Kade username (e.g., "bob's Pepperoni Feast").

Building a Portal

Properties

  • A Portal Property is a meta tag with a property and content value.

    <meta property="kd:portal:version" content="0.0.17" />

    Translates to:

    {
      "version": "0.0.17"
    }

Required Properties

Meta TagContent

kd:portal:version

The Portal version, equal to the official Portal Parser version

  • Note: Specifying only the version will render the portal invalid, defaulting to the OG image from the link.

Optional Properties

Meta TagContent

kd:portal:image

URL to the main image of the portal

kd:portal:image:aspect_ratio

Aspect ratio of the image (default: 1.91:1)

kd:portal:button:id

Button's title, identified by a number (1-4)

kd:portal:button:id:action

Action triggered by the button (mint, tx, post, link)

kd:portal:button:id:target

Target URL for the Portal signature, varies by action

kd:portal:button:id:function

Smart contract function name for in-app transactions

kd:portal:button:id:arguments

Serialized transaction arguments

kd:portal:button:id:type:arguments

Serialized type arguments

kd:portal:input

Placeholder for user input (e.g., email collection)

Button Actions

post

<meta name="kd:portal:button:1" content="Order Pizza" />
<meta name="kd:portal:button:1:action" content="post" />
<meta name="kd:portal:button:1:target" content="https://pizza-portal.xyz" />
  • Triggers a POST request to the target URL, with the response expected to be a 302 redirect to the next Portal.

tx

<meta name="kd:portal:button:1" content="Tickle cat" />
<meta name="kd:portal:button:1:action" content="tx" />
<meta name="kd:portal:button:1:target" content="https://tapos-portal.xyz" />
<meta name="kd:portal:button:1:function" content="module_address::module_name::function_name" />
<meta name="kd:portal:button:1:arguments" content="address_x::portal_argument_separator::2" /> 
<meta name="kd:portal:button:1:type:arguments" content="A::portal_argument_separator::B" />
  • Prompts the user to sign and submit a transaction, which includes the transaction hash in the Portal Packet.

mint

  • Similar to tx, but displays the acquired asset to the user upon transaction simulation.

link

  • Opens a link without sending a Portal Packet to the server.

Multi-Portal dApp

  • Mini apps built on Portals usually consist of multiple screens, with server-side logic determining the next screen.

Portal Packets

  • Portal Packets are sent to the server when a button with mint, tx, or post action is pressed, verifying user actions.

  • Example structure:

    interface PortalPacket {
        // the client's delegate address
        delegate_address: string,
        // the main user's address 
        user_address: string,
        // when the button was pressed
        timestamp: number,
        // incase we have an input field this will contain it's value
        input_text?: string,
      // in case of a tx or mint button actions, this will contain the transaction hash
        hash?: string
        // the button which was just pressed
        active_button: PortalButtonDefinition
        // the kid of the post that had this portal
        post_kid: string
        // the ref to the post
        post_ref: string
        // a signature of the current portal packet, signed by either the main user or their delegate's private key
        portal_signature?: string
    }

Portal Parsers

  • To simplify working with portals, we're developing tools for serializing and deserializing portal meta tags both server-side and client-side.

Current Availability and Future Tooling

  • Exclusive to Poseidon: Currently, Portals are exclusively available on the [Poseidon](https://play.google.com/store/apps/details?id=com.kadenet.poseidon&pcampaignid=web_share) application. They are still in an experimental phase and are actively being developed by the Kade team. The Poseidon app, will currently only load portals from our sites, or any partners looking to collaborate.

  • Exclusive Portal Loading on Poseidon: Currently, the Poseidon app only loads portals from our official sites or from our partners who are collaborating with us.

  • Ongoing Development: As we continue to refine and enhance the Portal specification, we aim to address any limitations and improve the overall user experience.

  • Future Tooling: We are working on developing comprehensive tooling to support the creation and management of Portals. This will include tools for serializing and deserializing portal meta tags, both server-side and client-side, to make it easier for developers to build and deploy Portals. Once the tooling is ready, it will be released to the community.

Last updated