DeHubOuvrir DeHub

DeHub › Documentation

Exemples pour développeurs DeHub — Code à copier-coller

De petits exemples complets pour ce dont la plupart des apps ont besoin en premier. Chacun fonctionne tel quel.

Une page de mini-app complète

<!doctype html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://riftn.com/sdk/miniapp.js"></script>
</head>
<body>
  <h1 id="hello">Hello</h1>
  <button id="share">Share</button>
  <script>
    (async () => {
      const { user } = await dehub.context;
      if (user) document.getElementById('hello').textContent = `Hello, ${user.displayName || user.handle}`;
      dehub.ready();

      document.getElementById('share').onclick = () =>
        dehub.actions.composePost({ text: 'I just tried this app', embedUrl: location.href });
    })();
  </script>
</body>
</html>

Connectez l’utilisateur sur votre serveur

// Express + jose
import express from 'express';
import { createRemoteJWKSet, jwtVerify } from 'jose';

const JWKS = createRemoteJWKSet(new URL('https://aigxuutjaqsywioxjefr.supabase.co/functions/v1/miniapp-auth'));
const app = express();

app.post('/api/session', async (req, res) => {
  try {
    const token = String(req.headers.authorization || '').replace(/^Bearer /, '');
    const { payload } = await jwtVerify(token, JWKS, { issuer: 'https://riftn.com', audience: 'tipjar.example.com' });
    res.json({ wallet: payload.sub });
  } catch {
    res.status(401).json({ error: 'Not signed in' });
  }
});

Un bouton de pourboire payé en DHB

document.getElementById('tip').onclick = async () => {
  try {
    const { receipt } = await dehub.actions.pay({ amount: 100, memo: 'Thanks!' });
    await fetch('/api/tips', { method: 'POST', headers: { 'Content-Type': 'text/plain' }, body: receipt });
    dehub.haptics.impact('heavy');
  } catch (error) {
    if (error.code !== 'rejected') alert(error.message);
  }
};
// Server: verify the receipt before you record the tip
const { payload } = await jwtVerify(receipt, JWKS, { issuer: 'https://riftn.com', audience: 'tipjar.example.com' });
if (payload.typ !== 'payment') throw new Error('Not a payment receipt');
// payload.sub paid payload.amount DHB in payload.txHash on chain payload.chainId

Notifier un joueur

await fetch('https://aigxuutjaqsywioxjefr.supabase.co/functions/v1/miniapp-notify', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.DEHUB_NOTIFY_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    notificationId: `turn-${game.id}-${game.turn}`,
    title: 'Your turn',
    body: `${opponent} made a move.`,
    targetUrl: `https://chess.example.com/game/${game.id}`,
    wallets: [player.wallet],
  }),
});

Demander aux gens d’ajouter votre app

const { client } = await dehub.context;
if (!client.added) {
  showBanner('Get a ping when it is your turn', async () => {
    try { await dehub.actions.addApp(); hideBanner(); } catch {}
  });
}

Un bouton Connexion avec DeHub pour n’importe quel site

// Node: start the login (register your app once first, see /docs/auth)
import crypto from 'node:crypto';

const verifier = crypto.randomBytes(32).toString('base64url');
const challenge = crypto.createHash('sha256').update(verifier).digest('base64url');
const state = crypto.randomBytes(16).toString('hex');
// Save verifier and state in the user's session, then redirect:
const url = new URL('https://riftn.com/oauth/authorize');
url.search = new URLSearchParams({
  response_type: 'code', client_id: CLIENT_ID, redirect_uri: REDIRECT_URI,
  scope: 'profile', state, code_challenge: challenge, code_challenge_method: 'S256',
});
res.redirect(url.toString());

Blog DeHub · Accueil de dehub.io