Skip to content

Commit 38dd815

Browse files
committed
Merge branch 'naga' of github.com:LIT-Protocol/js-sdk into feature/jss-132-naga-test-allow-naga-local-configuration
2 parents d13e64a + cee0425 commit 38dd815

File tree

3 files changed

+133
-78
lines changed

3 files changed

+133
-78
lines changed

docs/sdk/getting-started/auth-services.mdx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,33 @@ Lit hosts default Auth Service instances so you can build without deploying infr
2424
| ----------- | ------------------------------------------- | ------------------------------ | ----- |
2525
| `naga-dev` | `https://naga-dev-auth-service.getlit.dev` | `https://login.litgateway.com` | Use Lit's hosted endpoints while you prototype. Configure your SDK or environment variables with the URLs in this table. |
2626
| `naga-test` | `https://naga-test-auth-service.getlit.dev` | `https://login.litgateway.com` | Start with the hosted endpoints for staging, then switch to your own infrastructure as you scale. |
27-
| `naga` | `Run your own (recommended)` | `Run your own (recommended)` | Lit does not operate public Auth Service or Login Server endpoints for `naga` |
27+
| `naga` | `Run your own (recommended)` | `Run your own (recommended)` | Lit does not (yet) operate public Auth Service or Login Server endpoints for `naga` |
2828

2929
<Note>
3030
The hosted services are best suited for prototyping. Self-host the Auth
3131
Service and Login Server for production traffic or when you need custom
3232
configuration.
3333
</Note>
3434

35+
## Payment Delegation APIs
36+
37+
The Auth Service also exposes lightweight endpoints that sponsor user requests on the network. These are the same APIs the Lit SDK calls when you use `litClient.authService.registerPayer` / `delegateUsers` from the Payment Manager guide.
38+
39+
- `POST /register-payer`
40+
- Headers: `x-api-key`.
41+
- Behaviour: generates a random `payerSecretKey`, hashes it with the API key, and derives a child wallet from `LIT_DELEGATION_ROOT_MNEMONIC`.
42+
- Response: `{ success, payerWalletAddress, payerSecretKey }`. The service **does not** persist the secret—you must store it securely (KMS, vault, etc.).
43+
- Rotation: call the endpoint again with the same API key to rotate the secret and derive a new child wallet.
44+
- `POST /add-users`
45+
- Headers: `x-api-key`, `payer-secret-key`; body is a JSON array of user addresses.
46+
- Behaviour: recomputes the same child wallet on the fly and calls `PaymentManager.delegatePaymentsBatch` so the payer sponsors those users.
47+
48+
<Tip>
49+
Running the Auth Service yourself keeps the derivation mnemonic and payer secrets inside your infrastructure. The Lit-hosted instance is great for quick starts, but you remain responsible for storing the returned `payerSecretKey`.
50+
</Tip>
51+
52+
If you prefer not to run an Auth Service at all, you can still sponsor users manually: create a payer wallet, fund it, and call `paymentManager.delegatePayments*` directly from your backend. See [Payment Manager Setup](/sdk/getting-started/payment-manager-setup#sponsoring-your-users-capacity-delegation-replacement) for sample code.
53+
3554

3655
### Install the SDK
3756

Lines changed: 111 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
---
2-
title: "Payment Manager Setup"
3-
description: "Configure payment system for the Lit JS SDK"
2+
title: 'Payment Manager Setup'
3+
description: 'Configure payment system for the Lit JS SDK'
44
---
55

66
<Warning>
7-
❗️ Currently free on the dev network, so no need to deposit funds. More
8-
details coming soon for test and production networks.
7+
❗️ Payment status by network:
8+
- **naga-dev** – usage is currently free; no deposits required.
9+
- **naga-test** – payments are enabled using test tokens (see faucet link
10+
below).
11+
- **Mainnet** – coming soon; mainnet payment details will be announced
12+
shortly.
913
</Warning>
1014

1115
<Note>
@@ -23,10 +27,11 @@ description: "Configure payment system for the Lit JS SDK"
2327

2428
The Payment Manager demonstrates Lit Protocol's payment system - a billing system for decentralised cryptographic services. Users pay for compute resources on the Lit network to access core services like:
2529

26-
- Encryption/Decryption - Secure data with programmable access control
27-
- PKP Signing - Cryptographic keys that can sign transactions based on conditions
28-
- Lit Actions - Serverless functions with cryptographic capabilities
29-
Similar to how you pay AWS for cloud computing, this\system ensures the decentralised network can sustain itself and pay node operators. You can deposit funds, request withdrawals with security delays, and manage balances for yourself or other users (enabling applications to sponsor their users' costs for better UX).
30+
- [Encryption/Decryption](/sdk/auth-context-consumption/encrypt-and-decrypt) - Secure data with programmable access control.
31+
- [PKP Signing](/sdk/auth-context-consumption/pkp-sign) - Cryptographic keys that can sign transactions based on conditions.
32+
- [Lit Actions](/sdk/auth-context-consumption/execute-js) - Serverless functions with cryptographic capabilities.
33+
34+
Similar to how you pay AWS for cloud computing, this system ensures the decentralised network can sustain itself and pay node operators. Each payer keeps a balance in the on-chain Lit Ledger contract funded with `$LITKEY` (or `$tstLPX` on testnet), which the network debits as requests execute. You can deposit funds, request withdrawals with security delays, and manage balances for yourself or other users (enabling applications to sponsor their users' costs for better UX).
3035

3136
<Steps>
3237
<Step title="Payment Manager Setup">
@@ -40,8 +45,9 @@ const litClient = await createLitClient({ network: nagaTest });
4045

4146
// 2. Get PaymentManager instance (requires account for transactions)
4247
const paymentManager = await litClient.getPaymentManager({
43-
account: yourAccount // viem account instance
48+
account: yourAccount // viem account instance
4449
});
50+
4551
````
4652

4753
</Step>
@@ -59,7 +65,7 @@ const { data: myAccount } = useWalletClient();
5965
6066
```typescript viem/accounts
6167
// 1. import the privateKeyToAccount function from viem/accounts
62-
import { privateKeyToAccount } from "viem/accounts";
68+
import { privateKeyToAccount } from 'viem/accounts';
6369

6470
// 2. Convert your private key to a viem account object that can be used for payment operations.
6571
const myAccount = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
@@ -74,7 +80,7 @@ const myAccount = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
7480
```typescript Deposit funds to your own account
7581
// 1. Deposit funds to your own account
7682
const result = await paymentManager.deposit({
77-
amountInEth: "0.1",
83+
amountInEth: '0.1',
7884
});
7985

8086
console.log(`Deposit successful: ${result.hash}`);
@@ -84,8 +90,8 @@ console.log(`Deposit successful: ${result.hash}`);
8490
```typescript Deposit for another user
8591
// 1. Deposit funds for another user
8692
const result = await paymentManager.depositForUser({
87-
userAddress: "0x742d35Cc6638Cb49f4E7c9ce71E02ef18C53E1d5",
88-
amountInEth: "0.05",
93+
userAddress: '0x742d35Cc6638Cb49f4E7c9ce71E02ef18C53E1d5',
94+
amountInEth: '0.05',
8995
});
9096

9197
console.log(`Deposit successful: ${result.hash}`);
@@ -97,78 +103,113 @@ console.log(`Deposit successful: ${result.hash}`);
97103

98104
</Steps>
99105

100-
## Payment Delegation
106+
## Payment Delegation / Sponsoring Your Users
101107

102-
The Payment Manager lets one account sponsor the execution costs of another. See the following full lifecycle: Alice funds her ledger, delegates limits to Bob, Bob spends from Alice's balance, and Alice later revokes access. The snippets below mirror that scenario so you can recreate it locally.
108+
<Steps>
109+
<Step title="Define spending limit">
103110

104-
- `Alice` is the sponsor. She configures spending limits and delegates them to Bob.
105-
- `Bob` is the delegate. He signs with his PKP and provides `userMaxPrice` that fits within Alice's limits.
106-
- When Bob spends funds, Alice's ledger balance decreases.
107-
- Alice can immediately revoke Bob's access; further requests then fail.
111+
Define spending limits for the users you want to sponsor (values are in wei).
108112

109-
```typescript
110-
import { createLitClient } from '@lit-protocol/lit-client';
111-
import { nagaTest } from '@lit-protocol/networks';
113+
<CodeGroup>
112114

113-
// Assume you've already funded Alice's ledger using depositForUser
114-
const litClient = await createLitClient({ network: nagaTest });
115-
const alicePaymentManager = await litClient.getPaymentManager({
116-
account: aliceViemAccount,
115+
```typescript
116+
await paymentManager.setRestriction({
117+
totalMaxPrice: '1000000000000000000', // 1 ETH equivalent limit
118+
requestsPerPeriod: '100', // max number of sponsored requests in a period
119+
periodSeconds: '3600', // rolling window (1 hour in this example)
117120
});
121+
```
118122

119-
// 1. Configure Alice's spending restrictions for all delegates
120-
await alicePaymentManager.setRestriction({
121-
totalMaxPrice: '1000000000000000000', // 1 ETH (wei string)
122-
requestsPerPeriod: '100',
123-
periodSeconds: '5',
124-
});
123+
</CodeGroup>
125124

126-
// 2. Delegate access to Bob's EOA address
127-
await alicePaymentManager.delegatePaymentsBatch({
128-
userAddresses: [bobAddress],
129-
});
125+
</Step>
126+
127+
<Step title="Delegate users">
128+
129+
With restrictions set, delegate one or more users to spend from your payer wallet.
130+
131+
<CodeGroup>
130132

131-
// 3. Optionally inspect Alice's ledger balance before Bob spends
132-
const before = await alicePaymentManager.getBalance({
133-
userAddress: aliceViemAccount.address,
133+
```typescript
134+
await paymentManager.delegatePaymentsBatch({
135+
userAddresses: ['0xAlice...', '0xBob...'],
134136
});
135-
console.log('Alice balance before Bob signs:', before.raw.availableBalance);
136137
```
137138

138-
When Bob signs, the execution is charged against Alice's ledger (as long as Bob's `userMaxPrice` is within Alice's configured limit).
139+
</CodeGroup>
140+
</Step>
141+
142+
<Step title="(Optional) Inspect Balance">
143+
144+
Optionally inspect Payer/Sponsor Ledger balance
145+
146+
<CodeGroup>
147+
```ts
148+
const balance = await paymentManager.getBalance({
149+
userAddress: viemAccount.address,
150+
});
151+
```
152+
</CodeGroup>
153+
</Step>
154+
155+
<Step title="Remove users (optional)">
156+
157+
Undelegate users when you no longer want to sponsor them.
158+
159+
<CodeGroup>
139160

140161
```typescript
141-
await litClient.chain.ethereum.pkpSign({
142-
authContext: bobAuthContext, // Created with Bob's account
143-
pubKey: bobPkpPublicKey,
144-
toSign: 'Hello, world!',
145-
userMaxPrice: 200000000000000000n, // 0.2 ETH in Wei
162+
await paymentManager.undelegatePaymentsBatch({
163+
userAddresses: ['0xAlice...'],
146164
});
147165
```
148166

149-
After Bob signs, Alice's balance drops. She can revoke Bob immediately using `undelegatePaymentsBatch`. Subsequent attempts by Bob will fail.
167+
</CodeGroup>
150168

151-
```typescript
152-
// 4. Confirm Alice's balance decreased
153-
const after = await alicePaymentManager.getBalance({
154-
userAddress: aliceViemAccount.address,
169+
</Step>
170+
</Steps>
171+
172+
## **Alternatively**
173+
174+
Manage delegation via the hosted or self-hosted Auth Service (see [Auth Services setup](/sdk/getting-started/auth-services) for the full flow).
175+
176+
## After Payment Delegation
177+
178+
**Users decrypt as normal** – we still call `litClient.decrypt` with an auth context; the network draws fees from the delegated payer instead of the user’s wallet.
179+
180+
<Note>
181+
ℹ️ `userMaxPrice` is recommended for sponsored sessions, typically the same value or less than the the restriction the sponsor set; optional guardrail when self-funded.
182+
</Note>
183+
184+
```typescript highlight={18}
185+
// Client-side decrypt with sponsored payments
186+
const authContext = await authManager.createEoaAuthContext({
187+
litClient,
188+
config: { account: walletClient },
189+
authConfig: {
190+
resources: [
191+
['access-control-condition-decryption', '*'],
192+
['lit-action-execution', '*'],
193+
],
194+
},
155195
});
156-
console.log('Alice balance after Bob signs:', after.raw.availableBalance);
157196

158-
// 5. Revoke Bob's access
159-
await alicePaymentManager.undelegatePaymentsBatch({
160-
userAddresses: [bobAddress],
197+
const response = await litClient.decrypt({
198+
data: encryptedData,
199+
unifiedAccessControlConditions: accs,
200+
authContext,
201+
chain: 'ethereum',
202+
userMaxPrice: 1000000000000000000n,
161203
});
162204
```
163205

164206
## Auth Service API Endpoints
165207

166-
Leverage the hosted Auth Service to manage delegation without exposing private keys in your application:
167-
168-
- `POST /register-payer` - Send your `x-api-key` header to receive a delegated payer address and `payerSecretKey`. Persist this secret securely; it is required for all future delegation calls.
169-
- `POST /add-users` - Provide headers `x-api-key` and `payer-secret-key` plus a JSON body containing an array of user addresses. The Auth Service uses the Payment Manager internally to delegate payments to each address in a single transaction.
208+
Leverage the hosted Auth Service to manage delegation without exposing private keys in your application. Full request/response details live in the [Auth Services setup guide](/sdk/getting-started/auth-services#payment-delegation-apis). In practice you will:
170209

171-
> The legacy capacity-credit minting flow has been removed. Payment delegation now interacts directly with the Payment Manager contracts.
210+
- Call `authService.registerPayer` (hosted or self-hosted) to derive a payer wallet + `payerSecretKey`.
211+
- Call `authService.delegateUsers` (`/add-users`) to sponsor a list of user addresses.
212+
- Or skip the service entirely and use the Payment Manager methods directly (example below).
172213

173214
```typescript
174215
import { createLitClient } from '@lit-protocol/lit-client';
@@ -177,38 +218,31 @@ import { nagaTest } from '@lit-protocol/networks';
177218
// 1. Create the Lit client for the naga-test environment
178219
const litClient = await createLitClient({ network: nagaTest });
179220

180-
const authServiceBaseUrl = 'https://naga-test-auth-service.getlit.dev';
181-
const apiKey = process.env.LIT_API_KEY!;
221+
const authServiceBaseUrl = 'https://naga-test-auth-service.getlit.dev/';
222+
const apiKey = process.env.YOUR_AUTH_SERVICE_API_KEY!;
182223

183224
// 3. Register a payer wallet (store the secret securely server-side)
184225
const registerResponse = await litClient.authService.registerPayer({
185-
authServiceBaseUrl,
186-
apiKey,
226+
authServiceBaseUrl,
227+
apiKey,
187228
});
188229

189230
console.log('Payer wallet:', registerResponse.payerWalletAddress);
190231
console.log('Payer secret (store securely!):', registerResponse.payerSecretKey);
191232

192233
// 4. Later on, delegate payments for multiple users using the saved secret
193234
const delegateResponse = await litClient.authService.delegateUsers({
194-
authServiceBaseUrl,
195-
apiKey,
196-
payerSecretKey: registerResponse.payerSecretKey,
197-
userAddresses: [
198-
'0x1234...abcd',
199-
'0xabcd...1234',
200-
],
235+
authServiceBaseUrl,
236+
apiKey,
237+
payerSecretKey: registerResponse.payerSecretKey,
238+
userAddresses: ['0x1234...abcd', '0xabcd...1234'],
201239
});
202240

203241
console.log('Delegation submitted with tx hash:', delegateResponse.txHash);
204242

205243
// 5. Continue to use the same payer secret for future delegation calls
206-
````
244+
```
207245

208246
### How the Auth Service derives payer wallets
209247

210-
- The service holds a single root mnemonic (`LIT_DELEGATION_ROOT_MNEMONIC`).
211-
- `/register-payer` combines the `x-api-key` header with a freshly generated `payerSecretKey`. That pair is hashed into a deterministic derivation index, which is then used with the root mnemonic to derive a unique child wallet.
212-
- The response includes the derived wallet address and the random `payerSecretKey`. The server does not store this secret; you must persist it securely on the client side.
213-
- Later, `/add-users` expects both headers (`x-api-key` and `payer-secret-key`). The service recomputes the same derivation index and wallet on the fly, so the same header pair always maps to the same child wallet.
214-
- Calling `/register-payer` again with the same API key issues a new random `payerSecretKey`, which leads to a different child wallet. Choose whether to rotate secrets or keep the original one depending on your application needs.
248+
- For hosted or self-hosted deployments, see the derivation and rotation notes in the [Auth Services guide](/sdk/getting-started/auth-services#payment-delegation-apis). Manual deployments can always provision and delegate entirely via the `PaymentManager` helper without touching these endpoints.

packages/lit-client/src/lib/LitClient/createLitClient.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,7 @@ export const _createNagaLitClient = async (
950950
pkpPublicKey: string | Hex;
951951
authContext: AuthContextSchema2;
952952
chainConfig: Chain;
953+
userMaxPrice?: bigint;
953954
}) => {
954955
const _pkpPublicKey = HexPrefixedSchema.parse(params.pkpPublicKey);
955956

@@ -965,6 +966,7 @@ export const _createNagaLitClient = async (
965966
toSign: data,
966967
authContext: params.authContext,
967968
bypassAutoHashing: options?.bypassAutoHashing,
969+
userMaxPrice: params.userMaxPrice,
968970
});
969971

970972
return res.signature;

0 commit comments

Comments
 (0)