Skip to content

Quickstart

This walks you from a new account to a working integration in Test: a key, a vault for one customer, a deposit into it and a payment out of it. Everything happens on Sepolia, Ethereum’s test network, where coin is free and worth nothing, so nothing here can cost you money.

You need Go 1.22 or later, or Node 20 or later, on a server or your own machine, and a crypto wallet that can send Sepolia ETH (any Ethereum wallet can, once switched to Sepolia).

  1. Create a Test account.

    Sign up at app.sotirea.com/sign-up. Your new organisation is a Test organisation: its networks are test networks, and Live opens only after you apply and Sotirea approves it. Everyone sets up two-factor sign-in on their first visit.

  2. Create an API key.

    In the console, open Developers, then API keys, and choose Create a key. Name it after what will use it, such as Quickstart. Under What it can do, choose Integration: it can open vaults, request payments, manage webhooks and read balances, but never approve a payment or manage people.

    Because Integration can move money, a second person who manages roles has to confirm it. If you are the only person in your organisation, nobody else could, so it takes effect at once.

    The key is shown once. Keep it on your server, in an environment variable or a secrets manager:

    Terminal window
    export SOTIREA_API=https://api.sotirea.com
    export SOTIREA_API_KEY=sot_test_EXAMPLEkeyEXAMPLEkeyEXAMPLEkeyEXAMPLE

    A Test key starts sot_test_. Authentication has the rest.

  3. Install a client.

    Terminal window
    go get sotirea.com/sdk/go # Go
    npm install @sotirea/sdk # TypeScript
  4. Check the key.

    client := sotirea.New(
    os.Getenv("SOTIREA_API"),
    os.Getenv("SOTIREA_API_KEY"),
    )
    me, _, err := client.GetMe(ctx)
    if err != nil {
    log.Fatal(err)
    }
    org := me.Organisation
    fmt.Printf("%s, in %s (%s)\n", me.Key.Name, org.Name, org.Environment)

    It prints the key’s name, your organisation and test. If it says unauthenticated instead, the key was copied incompletely or has been revoked.

  5. Open a vault for a customer.

    Give each customer their own vault, named by your own id for them, here cust_1001. Asking again with the same reference answers the same vault rather than opening another, so you can call this whenever a customer needs their address without remembering whether you already did.

    vault, _, err := client.CreateVault(ctx, sotirea.VaultRequest{
    Reference: "cust_1001",
    })
    if err != nil {
    log.Fatal(err)
    }
    for _, a := range vault.Addresses {
    if a.ChainID == sepolia {
    fmt.Printf("Pay vault %d at %s\n", vault.ID, a.Address)
    }
    }

    The vault lists an address for every network your organisation can use, and it is the same address on each. Nothing is written to any network yet: the vault is created on a network the first time it pays out there, and it can receive before that.

  6. Receive a test deposit.

    From your wallet, send a little Sepolia ETH to the vault’s address. Then list what has arrived:

    deposits, err := client.ListDeposits(ctx, sotirea.ListDepositsParams{
    Vault: vault.ID,
    })
    if err != nil {
    log.Fatal(err)
    }
    for _, d := range deposits.Items {
    // arriving: seen on the network, not yet final.
    // received: final, and in the vault's balance.
    fmt.Println(d.State, d.Amount, d.Symbol, "from", d.From)
    }

    The deposit shows as arriving within a few minutes of being sent: Sotirea reads test networks every two minutes. On Sepolia it becomes received about 15 minutes later, once the network has made it final, and only then is it in the vault’s spendable balance. Webhooks can tell your server about each step instead of your code asking.

  7. Top up the network fees.

    Every payment pays the network a fee, in the network’s own coin. Sotirea pays it from a pool your organisation tops up, one per network, never from the vault or the amount you send. In the console, open Network fees, choose Sepolia under Add coin and send some Sepolia ETH to the address shown. Network fees has the detail.

  8. Send a payment.

    First ask what the payment would come to: whether your payment rules allow it and whether the fee pool covers it. Then send it, with an Idempotency-Key that names it.

    pay := sotirea.PaymentRequest{
    VaultID: vault.ID,
    ChainID: sepolia,
    To: os.Args[1],
    Amount: "1000000000000000", // 0.001 ETH: ETH has 18 decimals
    Reference: "payout-42",
    }
    quote, _, err := client.QuotePayment(ctx, pay)
    if err != nil {
    log.Fatal(err)
    }
    if quote.Outcome != "allowed" || !quote.GasPoolCovers {
    log.Fatalf("not sending: %s %s", quote.Outcome, quote.Reason)
    }
    // The Idempotency-Key, "payout-42", names this payment. If the
    // answer is lost, sending the same request again answers the same
    // payment: it never pays twice.
    payment, _, err := client.SendPayment(ctx, "payout-42", pay)
    if err != nil {
    log.Fatal(err)
    }
    fmt.Println(payment.ID, payment.Status)

    The answer comes at once, with the payment requested. It moves on to signed, sent, and confirmed once final. Follow it with Get a payment using the id it answered, which is api: followed by your organisation’s id and the Idempotency-Key.

    The vault’s first payment on a network also creates the vault there, so its fee is a little higher. The quote includes that.

A Live key, starting sot_live_, runs the same code against real networks and real money, once your organisation has been approved for Live. Apply from Go live in the console. The network ids change, from Sepolia (eip155:11155111) to Ethereum (eip155:1) for example, and nothing else in your code has to.