Mode démo : une boutique de référence pour les opérateurs eSIM. Prix réels, paiements désactivés. Lancer votre propre opérateur →
Travel eSIM · demo
Français

Votre propre hub

Sommaire

Il y a deux façons de mettre vos offres eSIM dans la fédération des agents IA. Les deux tiennent en une commande.

./onboard.sh          # un nœud de fédération : les hubs qui vous admettent listent vos offres
./onboard.sh --hub    # votre propre hub : il liste lui-même vos offres et se fédère avec les autres

Cette page porte sur la seconde : ce que votre propre hub vous apporte et ce qu'il n'apporte pas, ce que fait la commande étape par étape, et comment une vente passe par lui.

1. Nœud ou hub

Nœud de fédération (aimarket node)Votre propre hub (aimarket hub)
Ce qui tourne sur votre domaineun petit service qui publie vos offres signéesun hub AIMarket complet : catalogue, recherche, routage, reçus
Qui liste vos offresles hubs qui vous admettentvotre hub, toujours ; et les hubs qui l'admettent
Si un hub vous retirevous n'êtes plus dans ce hubvous restez dans le vôtre et dans tous les autres hubs qui vous ont admis
Comment les agents vous trouventvia un hubvia tout hub qui vous liste, ou directement sur https://<votre domaine>/ai-market/v2/search et MCP https://<votre domaine>/ai-market/mcp
Ce que les agents trouvent sur votre domainevos offresvos offres et le catalogue de toute la fédération, que votre hub parcourt
Reçussignés par le hub qui route l'appelvotre hub signe chaque appel qu'il route
Ce qu'il faut sauvegarderdata/node/ (la clé du nœud)data/hub/ (clés, base, réglages, jeton d'administrateur)
Entretienrien au-delà du kitun hub à tenir à jour (version d'aimarket-hub dans hub/Dockerfile)

Choisissez le nœud pour démarrer vite sans rien changer de votre côté. Choisissez le hub si vous voulez être listé quoi que décide un hub donné, donner aux agents votre propre adresse de recherche et MCP, ou tenir un catalogue à vous. Vous pouvez commencer par le nœud et passer au hub plus tard : la commande garde l'identité de votre domaine (section 6).

flowchart LR
    subgraph N["Nœud de fédération"]
        A1["Agent IA"] --> H1["un hub, p. ex. modelmarket.dev"]
        H1 -- "parcourt, route les devis" --> NN["votre nœud"]
        NN --> R1["votre nœud vendeur /agents"]
    end
    subgraph O["Votre propre hub"]
        A2["Agent IA"] --> H2["n'importe quel hub de la fédération"]
        A2 -- "ou directement chez vous" --> OH["votre hub"]
        H2 -- "parcourt, route les devis" --> OH
        OH --> R2["votre nœud vendeur /agents"]
    end

2. Ce que « garanti » veut dire ici

3. La commande

Sur le serveur, dans le dossier du kit :

./onboard.sh --hub

Elle ne demande que ce qui manque : votre domaine, le nom de la boutique, l'identifiant de vos offres et les clés du grossiste (saisies masquées, écrites dans secrets/, jamais affichées). Elle fait tout le reste elle-même, et on peut la relancer. Une exécution abrégée :

1. The server
  ✓ docker compose 2.29.7
2. Your settings (.env)
  ✓ esim.example.com · My Travel eSIM · esim-mytravel · demo mode (sells nothing yet)
  ✓ esim.example.com resolves to 203.0.113.10
3. Keys (secrets/, typed in hidden)
  ✓ secrets/esimaccess_access_code
  ✓ secrets/esimaccess_secret_key
4. Folders
  ✓ data/ and secrets/ belong to the containers' user (1000)
5. Store, seller node and HTTPS
  ✓ seller node: 1728 offers, 205 countries
6. Your own hub (aimarket hub)
  ✓ listed hub-hello/hub.ping@v1 free (signed receipt — what other hubs' sandbox runs)
  ✓ listed hub-hello/hub.hello@v1 at $0.004/call (local, executable, yours)
  ✓ listed esim-mytravel/esim.quote@v1 free → https://esim.example.com/agents/quote/invoke
  ✓ the hub lists esim.quote@v1 of esim-mytravel, signed with your seller node's key
  ✓ the federation reads you at https://esim.example.com/.well-known/ai-market.json
7. The admission check other hubs will run on you
  verdict: pass
8. Join the federation
  Knock on https://modelmarket.dev now? [Y/n]

./onboard.sh --check ne change rien et dit ce qui est prêt. --no-announce saute l'annonce ; --announce s'annonce sans demander. Si nginx occupe déjà les ports 80 et 443, la commande propose de placer le kit derrière, comme l'explique « Le chemin court » du guide de l'opérateur.

4. Ce que fait la commande

Pour qui veut savoir, ou le faire à la main. Les étapes 1 à 5 sont les mêmes que pour le nœud et installent la boutique et le nœud vendeur (guide de l'opérateur, étapes 4 à 7). Ensuite :

L'identité du hub. Si le domaine faisait déjà tourner un nœud de fédération, sa clé passe dans le hub, et les hubs qui connaissent votre domaine continuent de lui faire confiance (section 6) :

cp -p data/node/node_signing_key data/hub/hub_signing_key      # seulement si le hub n'a pas encore de clé

Le hub, une fois. quickstart enregistre les réglages du hub dans data/hub/aimarket.env (avec un jeton d'administrateur généré), crée ses clés de signature (Ed25519 et la post-quantique ML-DSA-65) et liste hub.ping@v1 : gratuit, il répond par un reçu signé par votre hub, et c'est ce qu'exécute le bac à sable d'admission des autres hubs. Il liste aussi hub.hello@v1, un bonjour payant qui montre qu'un appel payé fonctionne, et crée une clé d'acheteur avec 0,05 $ de crédit de test sur votre hub ; la commande n'affiche pas cette clé.

docker compose --profile hub build hub
docker compose --profile hub run --rm hub quickstart --name "$STORE_NAME" --url "https://$DOMAIN"

Vos offres dessus. Le hub appelle votre nœud vendeur à chaque devis et vérifie la signature du nœud sur la réponse, avec la clé qu'il lit sur le nœud lui-même :

PUB=$(curl -s "https://$DOMAIN/agents/healthz" | sed -n 's/.*"provider_pubkey":"\([^"]*\)".*/\1/p')
docker compose --profile hub run --rm hub add esim.quote@v1 \
  --url "https://$DOMAIN/agents/quote/invoke" --product "$PRODUCT_ID" \
  --name "Travel eSIM offers" \
  --description "Travel eSIM offers for a country: data, days and price in USDC; the answer names the order URL, paid over x402" \
  --input-schema @/spec/quote-input.schema.json --provider-pubkey "$PUB"

La bascule. Caddy envoie les chemins de la fédération (/.well-known/ai-market.json, /ai-market/*, /a2a, /mcp, /.well-known/agent-card.json) au hub au lieu du nœud :

echo "FEDERATION_UPSTREAM=hub:9083" >> .env
docker compose --profile federation stop node
docker compose --profile hub up -d hub
docker compose up -d caddy

La vérification. aimarket doctor fait passer à votre hub la vérification d'admission que les autres hubs feront, depuis l'extérieur, et dit quoi corriger pour chaque ligne en échec :

docker compose --profile hub exec hub aimarket doctor

L'annonce. Le hub auprès duquel vous vous annoncez fait lui-même cette vérification dans un bac à sable, et vous liste quand elle passe :

curl -s -X POST https://modelmarket.dev/ai-market/v2/federation/announce -H 'Content-Type: application/json' \
  -d "{\"hub_url\": \"https://$DOMAIN\", \"hub_name\": \"$STORE_NAME\"}"

La réponse porte assay_url, où se lit le verdict. Annoncez-vous auprès d'autant de hubs que vous voulez, de la même manière.

5. Comment tout s'assemble

flowchart TB
    subgraph D["Votre serveur : https://esim.example.com (Caddy, HTTPS)"]
        S["store/ · / — votre boutique pour les gens"]
        R["rails/ · /agents/* — nœud vendeur : devis, commande (x402), statut, remboursement"]
        H["hub/ · /.well-known/ai-market.json, /ai-market/*, /a2a, /mcp — votre hub"]
        H -- "POST /agents/quote/invoke, réponse signée avec la clé du vendeur" --> R
    end
    A["Agent IA"] -- "recherche, devis (gratuit)" --> H
    A -- "x402 : la commande, payée sur votre portefeuille" --> R
    A -- "statut, remboursement (jeton de statut)" --> R
    F["Autres hubs : modelmarket.dev, …"] -- "vérification d'admission, puis parcours de votre manifeste signé" --> H
    F -- "devis routés de leurs acheteurs" --> H
    H -- "parcourt leurs catalogues" --> F
    W["eSIM Access / Airalo / eSIM Go / votre système"] --- R

Une vente via la fédération, par un agent qui a cherché sur un autre hub :

sequenceDiagram
    autonumber
    participant A as Agent IA
    participant M as modelmarket.dev
    participant H as Votre hub
    participant R as Votre nœud vendeur
    participant C as Base (USDC)
    A->>M: recherche intent=esim
    M-->>A: esim.quote@v1 de esim-mytravel, source_hub https://esim.example.com
    A->>M: invoke esim.quote@v1 {country: TR}
    M->>H: appel routé
    H->>R: POST /agents/quote/invoke
    R-->>H: offres, signées (X-Provider-Signature)
    H->>H: signature vérifiée avec votre clé de vendeur, reçu signé
    H-->>M: offres + le reçu de votre hub
    M-->>A: offres, URL de commande https://esim.example.com/agents/order
    A->>R: POST /agents/order → 402, puis PAYMENT-SIGNATURE (EIP-3009)
    R->>C: le facilitateur règle : USDC sur votre portefeuille
    R-->>A: l'eSIM + un reçu de livraison signé avec votre clé de vendeur
    A->>M: le reçu et sa transaction (facultatif)
    M->>M: compté sur votre listing : deliveries_30d

L'argent ne passe jamais par un hub : l'agent paie votre portefeuille via x402, comme avec le nœud.

6. Admission, clés et passage depuis le nœud

stateDiagram-v2
    [*] --> pending: vous vous annoncez (announce)
    pending --> checking: le bac à sable du hub appelle votre hub.ping@v1 gratuit
    checking --> admitted: reçu signé, manifeste et clés valides → pass
    checking --> pending: review ou fail : l'opérateur du hub décide
    admitted --> listed: le hub parcourt votre manifeste
    listed --> listed: nouveau parcours ; les nouvelles offres apparaissent seules
    listed --> rejected: votre clé a changé (prise de contrôle possible)
    rejected --> listed: l'opérateur de ce hub épingle votre nouvelle clé

7. Réglages

RéglageOùCe qu'il fait
FEDERATION_UPSTREAM.envhub:9083 envoie les chemins de la fédération à votre hub ; vide pour le nœud. Réglé par la commande.
HUB_DESCRIPTION.envUne phrase sur votre boutique à côté de son nom sur les autres hubs, dans les annuaires et sur l'Alien Monitor (3.15.28 et plus).
PROXY.envcaddy (celui du kit), nginx (le vôtre, configuré par la commande) ou external (le vôtre, configuré par vous). Réglé par la commande.
AIMARKET_HUB_URL, AIMARKET_HUB_NAMEdocker-compose.ymlhttps://<DOMAIN> et STORE_NAME : l'adresse et le nom de votre hub dans chaque document qu'il signe.
AIMARKET_SUPPLY_REQUIRE_RESPONSE_SIGdocker-compose.yml1 : chaque réponse de votre nœud vendeur doit porter sa signature.
AIMARKET_TRUSTED_PROXIESdocker-compose.ymlLes réseaux de Caddy : le hub voit l'adresse réelle de chaque appelant pour ses limites.
AIMARKET_ROUTING_FEE_BPSdata/hub/aimarket.envVotre commission quand votre hub route la vente de la capacité d'un autre hub sur ses crédits (1 % par défaut). Les ventes de vos eSIM paient votre portefeuille en entier.
AIMARKET_ORACLE_FAMILY_URLdata/hub/aimarket.envoff (réglé par quickstart) : votre hub note lui-même les éditeurs et ne dépend de personne.
version d'aimarket-hubhub/DockerfileMise à jour : docker compose --profile hub build --pull hub && docker compose --profile hub up -d hub.

Le hub a bien d'autres réglages (crédits, listings d'autres personnes, canaux de paiement) : voir faire tourner votre propre hub. Aucun n'est nécessaire pour vendre des eSIM.

8. Versions

9. Limites

Le kit sur GitHub →