> ## Documentation Index
> Fetch the complete documentation index at: https://vowena-dependabot-github-actions-actions-checkout-7.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Go from zero to a working on-chain subscription in 5 minutes. Install the Vowena SDK, create a project and plan, subscribe a wallet, charge, and cancel.

Get a complete subscription lifecycle running on Stellar testnet in under 5 minutes.

<Info>
  You'll need Node.js 20+, a funded Stellar testnet account, and a USDC
  trustline. The [dashboard checkout page](https://dashboard.vowena.xyz) can
  fund a fresh wallet via friendbot if you don't have one.
</Info>

<Steps>
  <Step title="Install the SDK">
    <CodeGroup>
      ```bash npm theme={null}
      npm install @vowena/sdk
      ```

      ```bash pnpm theme={null}
      pnpm add @vowena/sdk
      ```

      ```bash yarn theme={null}
      yarn add @vowena/sdk
      ```
    </CodeGroup>

    <Tip>
      The SDK is a lightweight wrapper around the Vowena Soroban contract. It
      builds transactions locally — you sign and submit them with your own
      wallet or keypair.
    </Tip>
  </Step>

  <Step title="Create a client">
    <Tabs>
      <Tab title="Testnet">
        ```typescript theme={null}
        import { VowenaClient, NETWORKS } from "@vowena/sdk";

        const client = new VowenaClient({
          contractId: NETWORKS.testnet.contractId,
          rpcUrl: NETWORKS.testnet.rpcUrl,
          networkPassphrase: NETWORKS.testnet.networkPassphrase,
        });
        ```
      </Tab>

      <Tab title="Mainnet">
        ```typescript theme={null}
        // Mainnet deployment coming after testnet pilots.
        import { VowenaClient, NETWORKS } from "@vowena/sdk";

        const client = new VowenaClient({
          contractId: NETWORKS.mainnet.contractId,
          rpcUrl: NETWORKS.mainnet.rpcUrl,
          networkPassphrase: NETWORKS.mainnet.networkPassphrase,
        });
        ```
      </Tab>

      <Tab title="Custom RPC">
        ```typescript theme={null}
        import { VowenaClient } from "@vowena/sdk";

        const client = new VowenaClient({
          contractId: "CABC...XYZ",
          rpcUrl: "https://your-rpc.example.com",
          networkPassphrase: "Test SDF Network ; September 2015",
        });
        ```
      </Tab>
    </Tabs>

    <Note>
      `NETWORKS.testnet` ships pre-configured `contractId`, `rpcUrl`,
      `networkPassphrase`, and `usdcAddress`.
    </Note>
  </Step>

  <Step title="Create a Project (merchant)">
    Every plan lives under a Project. Create one first.

    ```typescript theme={null}
    const projectTx = await client.buildCreateProject({
      merchant: "GMERCHANT...ADDR",
      name: "Acme SaaS",
      description: "Recurring billing for Acme's hosted product.",
    });

    const projectResult = await client.submitTransaction(await sign(projectTx));
    // Fetch the newly created project_id from the merchant's project list
    const projectIds = await client.getMerchantProjects(
      "GMERCHANT...ADDR",
      "GMERCHANT...ADDR",
    );
    const projectId = projectIds[projectIds.length - 1];
    ```
  </Step>

  <Step title="Create a Plan (merchant)">
    ```typescript theme={null}
    import { toStroops, NETWORKS } from "@vowena/sdk";

    const planTx = await client.buildCreatePlan({
      merchant: "GMERCHANT...ADDR",
      token: NETWORKS.testnet.usdcAddress,
      amount: toStroops("9.99"),           // 9.99 USDC per period
      period: 2_592_000,                   // 30 days
      priceCeiling: toStroops("14.99"),    // max price within this plan
      trialPeriods: 1,                     // 1 free period
      maxPeriods: 0,                       // 0 = unlimited
      gracePeriod: 259_200,                // 3 days grace on failed charges
      name: "Pro",                         // display name
      projectId,                           // parent project from step 3
    });

    const planResult = await client.submitTransaction(await sign(planTx));
    ```

    <Accordion title="What does toStroops do?">
      Converts a human-readable amount to the 7-decimal integer format used
      by Stellar tokens:

      ```typescript theme={null}
      toStroops("9.99"); // → 99900000n
      toStroops("1.00"); // → 10000000n
      ```
    </Accordion>
  </Step>

  <Step title="Subscribe (subscriber)">
    One signature creates the subscription AND sets the SAC allowance. If the
    plan has no trial, the first period is charged atomically during this
    call.

    ```typescript theme={null}
    const subTx = await client.buildSubscribe(
      "GSUBSCRIBER...ADDR",
      planId,
      // Optional: tune the allowance explicitly
      { allowancePeriods: 24 },
    );

    const subResult = await client.submitTransaction(await sign(subTx));
    ```

    <Tip>
      The subscriber's wallet displays exactly what's being approved: the
      token (USDC), the spending ceiling (`price_ceiling × allowance_periods`),
      and the Vowena contract as spender. Full transparency.
    </Tip>
  </Step>

  <Step title="Charge (keeper or anyone)">
    Once a billing period has elapsed, anyone can fire the charge. The
    contract does all the validation on-chain.

    ```typescript theme={null}
    const chargeTx = await client.buildCharge("GKEEPER...ADDR", subId);
    await client.submitTransaction(await sign(chargeTx));
    ```

    The contract checks:

    * Is the subscription active?
    * Has `period` seconds passed since the last charge?
    * Is the trial over?
    * Does the subscriber have sufficient balance and allowance?
    * Has `max_periods` been reached?

    If all checks pass, USDC moves from subscriber to merchant via the SAC's
    `transfer_from`.

    <Info>
      You don't have to run your own keeper. The [Vowena
      dashboard](/dashboard/keeper-setup) ships a managed keeper cron that
      fires every minute.
    </Info>
  </Step>

  <Step title="Cancel">
    Either party can cancel, any time.

    ```typescript theme={null}
    const cancelTx = await client.buildCancel("GSUBSCRIBER...ADDR", subId);
    await client.submitTransaction(await sign(cancelTx));
    ```

    <Note>
      Cancellation is immediate and on-chain. Subscribers can also cancel
      directly via any Soroban-aware wallet or block explorer — the Vowena
      frontend is not required.
    </Note>
  </Step>
</Steps>

***

## Full example

```typescript theme={null}
import { VowenaClient, NETWORKS, toStroops } from "@vowena/sdk";

const client = new VowenaClient({
  contractId: NETWORKS.testnet.contractId,
  rpcUrl: NETWORKS.testnet.rpcUrl,
  networkPassphrase: NETWORKS.testnet.networkPassphrase,
});

// 1. Create a project
const projectTx = await client.buildCreateProject({
  merchant: "GMERCHANT...ADDR",
  name: "Acme SaaS",
  description: "",
});
await client.submitTransaction(await sign(projectTx));
const [projectId] = (
  await client.getMerchantProjects("GMERCHANT...ADDR", "GMERCHANT...ADDR")
).slice(-1);

// 2. Create a plan
const planTx = await client.buildCreatePlan({
  merchant: "GMERCHANT...ADDR",
  token: NETWORKS.testnet.usdcAddress,
  amount: toStroops("9.99"),
  period: 2_592_000,
  priceCeiling: toStroops("14.99"),
  trialPeriods: 0,
  maxPeriods: 12,
  gracePeriod: 259_200,
  name: "Pro",
  projectId,
});
await client.submitTransaction(await sign(planTx));
const [planId] = (
  await client.getMerchantPlans("GMERCHANT...ADDR", "GMERCHANT...ADDR")
).slice(-1);

// 3. Subscriber subscribes (first period charges atomically since trial=0)
const subTx = await client.buildSubscribe("GSUB...ADDR", planId);
await client.submitTransaction(await sign(subTx));
const [subId] = (
  await client.getSubscriberSubscriptions("GSUB...ADDR", "GSUB...ADDR")
).slice(-1);

// 4. After the next period elapses, anyone can charge
const chargeTx = await client.buildCharge("GKEEPER...ADDR", subId);
await client.submitTransaction(await sign(chargeTx));

// 5. Cancel
const cancelTx = await client.buildCancel("GSUB...ADDR", subId);
await client.submitTransaction(await sign(cancelTx));
```

***

## Next steps

<CardGroup cols={2}>
  <Card title="Core concepts" icon="lightbulb" href="/concepts">
    Projects, plans, subscriptions, allowances, and the billing lifecycle in
    depth.
  </Card>

  <Card title="How it works" icon="diagram-project" href="/how-it-works">
    Visual walkthrough of the full protocol flow — plan creation to
    cancellation.
  </Card>

  <Card title="SDK reference" icon="code" href="/sdk/client">
    Every method, type, and configuration option.
  </Card>

  <Card title="Run a keeper" icon="robot" href="/sdk/keeper">
    Set up an automated keeper to charge subscriptions on schedule.
  </Card>
</CardGroup>
