OutLayer Documentation

Payment Keys

Payment Keys enable HTTPS API access to OutLayer projects without NEAR transactions. Users prepay in USD stablecoins and spend from their balance with simple HTTP requests.

What are Payment Keys?#

A Payment Key is a secret token linked to your NEAR account with a prepaid USD balance. It allows you to call OutLayer projects via HTTPS API without signing NEAR transactions.

Key benefits:

  • No blockchain transactions per API call (only key setup/withdrawal)
  • Sub-second response times
  • Easy integration with existing backends
  • USD stablecoin payments (USDT/USDC)

Key Format#

Payment Keys are passed in the X-Payment-Key HTTP header:

X-Payment-Key: {owner}:{nonce}:{secret}

Example: X-Payment-Key: alice.near:0:K7xR2mN9pQs5vW3yZ8bF...
PartDescriptionExample
ownerYour NEAR account IDalice.near
nonceKey number (1, 2...)1
secret32-byte random token (Base64)K7xR2mN9pQs5vW3yZ8bF...

The secret is a 32-byte cryptographically random value encoded in Base64 (44 characters). It's generated client-side and shown only once during creation.

Creating Payment Keys#

Creating a Payment Key requires two transactions:

  1. Create the key - Stores encrypted key data on-chain via store_secrets
  2. Initial deposit - Transfers stablecoins via ft_transfer_call to fund the key

Via Dashboard#

  1. Go to /payment-keys
  2. Click "Create Payment Key"
  3. Configure restrictions (see below)
  4. Enter initial deposit amount (minimum $1)
  5. Sign both transactions in your wallet
  6. Copy the key immediately - it's shown only once!

Critical: The secret key is displayed only once after creation. Copy it immediately and store securely (e.g., password manager, environment variable). If lost, you must create a new key.

Via CLI#

# Step 1: Generate random key (32 bytes in Base64)
SECRET_KEY=$(openssl rand -base64 32)
echo "Your secret key: $SECRET_KEY"

# Step 2: Create key on contract (initial_balance = 0)
near call outlayer.near store_secrets '{
  "accessor": {"System": "PaymentKey"},
  "profile": "0",
  "encrypted_data": "<encrypted JSON with key>"
}' --accountId alice.near --depositYocto 1

# Step 3: Top up with stablecoins
near call usdt.tether-token.near ft_transfer_call '{
  "receiver_id": "outlayer.near",
  "amount": "10000000",
  "msg": "{\"action\": \"top_up_payment_key\", \"nonce\": 0}"
}' --accountId alice.near --depositYocto 1

Key Restrictions#

Payment Keys can be restricted to limit their capabilities for security:

Project Restrictions#

OptionDescriptionUse Case
Any projectKey works with all OutLayer projectsGeneral-purpose API access
Specific projectsKey only works with selected projects (e.g., alice.near/my-app)Production keys for specific services
// Key restricted to specific projects
{
  "key": "K7xR2mN9pQs5vW3yZ8bF...",
  "initial_balance": "10000000",
  "project_ids": ["alice.near/weather-api", "alice.near/ai-assistant"],
  "max_per_call": "1000000"
}

Spending Limits#

max_per_call

Maximum amount that can be spent in a single API call (compute + attached deposit combined).

Example: max_per_call: "1000000" limits each call to $1.00 maximum.

Security tip: For production keys, always set both project restrictions and spending limits to minimize damage if a key is compromised.

Balance Management#

Checking Balance#

View your key balance on the Payment Keys dashboard page. The balance shows:

  • Initial balance - Total amount deposited
  • Spent - Amount already used
  • Available - Remaining balance (initial - spent)

Topping Up Balance#

Add more funds to an existing key:

  1. Go to /payment-keys
  2. Find your key and click "Top Up"
  3. Enter amount (minimum $1)
  4. Sign the ft_transfer_call transaction
# Top up via CLI (add $10 USDT to key with nonce 0)
near call usdt.tether-token.near ft_transfer_call '{
  "receiver_id": "outlayer.near",
  "amount": "10000000",
  "msg": "{\"action\": \"top_up_payment_key\", \"nonce\": 0}"
}' --accountId alice.near --depositYocto 1

Balance Protection#

OutLayer uses a reserved balance mechanism to prevent overdraft attacks:

  1. When a call starts, the estimated cost is reserved
  2. Call is rejected if available - reserved < estimated_cost
  3. After completion, actual cost is charged and reservation is released

This prevents an attacker from spending $90 with a $1 balance by launching many parallel requests.

How Keys are Stored#

Payment Key data is stored as an encrypted secret on the OutLayer contract:

// Encrypted data structure (decrypted only in TEE)
{
  "key": "K7xR2mN9pQs5vW3yZ8bF...",      // 32-byte secret
  "initial_balance": "10000000",          // Total deposited (micro-units)
  "project_ids": ["alice.near/my-app"],   // Allowed projects ([] = any)
  "max_per_call": "1000000"               // Spending limit per call
}

On-Chain (Contract)

  • Encrypted key data
  • Owner (NEAR account)
  • Nonce (key number)

Off-Chain (Coordinator)

  • Spent amount (running total)
  • Reserved amount (in-flight)
  • Usage history (audit log)

Security: The secret key is encrypted with TEE keys and can only be decrypted inside the Trusted Execution Environment during API validation. The coordinator never sees the plaintext key - it only validates hashes.

Rate Limits#

To prevent abuse, Payment Keys have rate limits:

LimitValueScope
Requests per minute (IP)100Before key validation
Requests per minute (Key)1000After key validation
Concurrent jobs per key10Simultaneous executions
Minimum compute limit$0.001Per request

Rate limit headers are included in responses:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1704067260

When limits are exceeded, you'll receive HTTP 429 Too Many Requests.

Security Best Practices#

1. Restrict to specific projects

Production keys should only work with the projects they need. Avoid "any project" keys.

2. Set spending limits

Always set max_per_call to limit damage from a compromised key.

3. Use environment variables

Never hardcode keys in source code. Use environment variables or secret managers.

4. Rotate keys periodically

Create new keys and revoke old ones regularly, especially after team changes.

5. Monitor usage

Regularly check the Payment Keys dashboard for unexpected spending patterns.

Related Documentation