Skip to content
Testnet only: a reference implementation, not a production service.Tokens and bank transfers here are simulated and have no value.

Quickstart

This page takes a hosted Testnet API key to a completed mint of 100.00 USDX. Every request below runs in CI against an in-process core on FakeChain, so a response that stops matching its # expect line fails the build.

You need an API key for an org with approved KYB and the counterparties:write and transfers:write scopes; the hosted issuer's dev-org command prints one. Three placeholders stand in for your values: {{KEY}} is your API key, {{uuid}} is a fresh idempotency key the runner fills in, and {{WALLET_ADDRESS}} is your funded Testnet wallet. On a hosted issuer you fund that wallet through Friendbot first:

curl -s "$API/v1/sandbox/testnet/fund" -H "authorization: Bearer $KEY" -H "idempotency-key: $(uuidgen)" \
  -H 'content-type: application/json' -d '{"address":"<WALLET_ADDRESS>"}'

The docs runner funds {{WALLET_ADDRESS}} before the first request, so the block above stays plain bash.

Register and prove the wallet

Create a stellar_wallet counterparty. The response carries an ownership challenge, and only the wallet's key can sign it. Lines starting with # are directives the docs runner reads, not part of the request: # expect is the status the request must return, # save carries a response value into a later request, and # sign stands in for signing a saved XDR with the page's test wallet. On a hosted issuer you sign locally instead, the way the README's sign.mjs does.

POST /v1/counterparties
authorization: Bearer {{KEY}}
idempotency-key: {{uuid}}
content-type: application/json

{
  "type": "stellar_wallet",
  "address": "{{WALLET_ADDRESS}}",
  "label": "quickstart"
}
# expect 201
# save CPTY = $.id
# save CHALLENGE = $.ownership_proof.challenge_xdr
# sign SIGNED_CHALLENGE = CHALLENGE

Submit the signed challenge. The wallet becomes active.

POST /v1/counterparties/{{CPTY}}/ownership-proof
authorization: Bearer {{KEY}}
idempotency-key: {{uuid}}
content-type: application/json

{
  "signed_challenge_xdr": "{{SIGNED_CHALLENGE}}"
}
# expect 200

Add the trustline

An active wallet still needs a trustline to the asset, and the issuer sponsors it. Ask for the offer, co-sign the returned envelope with the wallet key, then submit the hash and the signed envelope together. The offer expires about a minute after it is issued, so keep the signing step close by.

POST /v1/counterparties/{{CPTY}}/sponsored-trustline
authorization: Bearer {{KEY}}
idempotency-key: {{uuid}}
content-type: application/json

{}
# expect 200
# save TRUSTLINE_HASH = $.hash
# save TRUSTLINE_ENVELOPE = $.envelope_xdr
# sign SIGNED_TRUSTLINE = TRUSTLINE_ENVELOPE
POST /v1/counterparties/{{CPTY}}/sponsored-trustline/submit
authorization: Bearer {{KEY}}
idempotency-key: {{uuid}}
content-type: application/json

{
  "hash": "{{TRUSTLINE_HASH}}",
  "signed_envelope_xdr": "{{SIGNED_TRUSTLINE}}"
}
# expect 200

Mint and settle the wire

Create a mint transfer from an inbound wire to the wallet. The response's deposit_instructions.reference is the wire reference. If the trustline has not landed yet this answers destination_no_trustline, so retry with a fresh idempotency key.

POST /v1/transfers
authorization: Bearer {{KEY}}
idempotency-key: {{uuid}}
content-type: application/json

{
  "source": { "type": "fiat", "currency": "USD", "rail": "wire" },
  "destination": { "type": "stellar", "asset": "USDX", "counterparty_id": "{{CPTY}}" },
  "amount": "100.00"
}
# expect 201
# save TRANSFER = $.id
# save REFERENCE = $.deposit_instructions.reference

Simulate the incoming wire with the sandbox endpoint, quoting the reference. A matching wire credits the org and the mint proceeds.

POST /v1/sandbox/fiat-deposits
authorization: Bearer {{KEY}}
idempotency-key: {{uuid}}
content-type: application/json

{
  "reference": "{{REFERENCE}}",
  "amount": "100.00",
  "currency": "USD"
}
# expect 201

Read the transfer back. It is completed once the mint has been submitted and confirmed on chain.

GET /v1/transfers/{{TRANSFER}}
authorization: Bearer {{KEY}}
# expect 200

The completed transfer carries a stellar_tx_hash; open it in an explorer to see the mint arrive in the wallet.

Edit on GitHub