dhali-js 2.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,4 +29,4 @@ jobs:
29
29
  run: npm test
30
30
 
31
31
  - name: Run lint
32
- run: npx tsc src/dhali/*.js --allowJs --checkJs --noEmit --moduleResolution node --module commonjs --target esnext
32
+ run: npx tsc src/dhali/*.js --allowJs --checkJs --noEmit --moduleResolution node --module commonjs --target esnext --skipLibCheck
package/README.md CHANGED
@@ -16,6 +16,9 @@ Includes support for **Machine-to-Machine (M2M) payments** using seamless off-ch
16
16
  npm install dhali-js
17
17
  ```
18
18
 
19
+ > [!TIP]
20
+ > The examples below use CommonJS (`require`). Because they use `await`, the code is wrapped in an `async function main() { ... }` which is called immediately. To run these, simply save them to a `.js` file and run `node document.js`.
21
+
19
22
  ---
20
23
 
21
24
  ## Quick Start: Machine-to-Machine Payments
@@ -28,69 +31,85 @@ Uses `xrpl.js` for local signing.
28
31
  const { Client, Wallet } = require('xrpl')
29
32
  const { DhaliChannelManager, ChannelNotFound, Currency } = require('dhali-js')
30
33
 
31
- const seed = "sXXX..."
32
- const wallet = Wallet.fromSeed(seed)
33
- const client = new Client("wss://s.altnet.rippletest.net:51233")
34
- await client.connect()
35
-
36
- const currency = new Currency("XRP", 6)
37
-
38
- // Use Factory
39
- const manager = DhaliChannelManager.xrpl(wallet, client, "XRPL.TESTNET", currency)
40
-
41
- // Generate Claim
42
- let token;
43
- try {
44
- token = await manager.getAuthToken();
45
- } catch (error) {
46
- if (error.name === "ChannelNotFound") {
47
- await manager.deposit(1000000); // Deposit 1 XRP
48
- token = await manager.getAuthToken();
49
- } else {
50
- throw error;
34
+ async function main() {
35
+ const seed = "sXXX..."
36
+ const wallet = Wallet.fromSeed(seed)
37
+ const client = new Client("wss://s.altnet.rippletest.net:51233")
38
+ await client.connect()
39
+
40
+ const currency = new Currency("XRPL.TESTNET", "XRP", 6)
41
+
42
+ // Use Factory
43
+ const manager = DhaliChannelManager.xrpl(wallet, client, currency)
44
+
45
+ // Generate Claim
46
+ let token;
47
+ try {
48
+ token = await manager.getAuthToken();
49
+ } catch (error) {
50
+ if (error.name === "ChannelNotFound") {
51
+ await manager.deposit(1000000); // Deposit 1 XRP
52
+ token = await manager.getAuthToken();
53
+ } else {
54
+ throw error;
55
+ }
51
56
  }
57
+ console.log('XRPL Token:', token);
52
58
  }
53
- console.log('XRPL Token:', token);
59
+
60
+ main();
54
61
  ```
55
62
 
56
63
  ### 2. Ethereum (EVM)
57
64
 
58
- Uses `ethers` (v6) for EIP-712 signing.
65
+ Uses `viem` for EIP-712 signing.
59
66
 
60
67
  ```js
61
- const { ethers } = require('ethers')
68
+ const { createWalletClient, createPublicClient, http } = require('viem')
69
+ const { privateKeyToAccount } = require('viem/accounts')
70
+ const { mainnet, sepolia } = require('viem/chains')
62
71
  const { DhaliChannelManager, getAvailableDhaliCurrencies } = require('dhali-js')
63
72
 
64
- // 1. Setup Signer
65
- const provider = new ethers.JsonRpcProvider("https://rpc.ankr.com/eth_sepolia")
66
- const signer = new ethers.Wallet("0x...", provider)
67
-
68
- // 2. Fetch Available Currencies
69
- const configs = await getAvailableDhaliCurrencies()
70
- const sepoliaUsdc = configs["SEPOLIA"]["USDC"]
71
-
72
- // 3. Instantiate Manager with Dynamic Config
73
- const manager = DhaliChannelManager.evm(
74
- signer,
75
- provider,
76
- "SEPOLIA",
77
- sepoliaUsdc.currency
78
- )
79
-
80
- // 4. Generate Claim
81
- // 4. Generate Claim
82
- let token;
83
- try {
84
- token = await manager.getAuthToken(1000000); // 1.00 USDC
85
- } catch (error) {
86
- if (error.name === "ChannelNotFound") {
87
- await manager.deposit(1000000); // Deposit 1.00 USDC
88
- token = await manager.getAuthToken(1000000);
89
- } else {
90
- throw error;
73
+ async function main() {
74
+ // 1. Setup Clients
75
+ const account = privateKeyToAccount('0x...')
76
+ const publicClient = createPublicClient({
77
+ chain: sepolia,
78
+ transport: http()
79
+ })
80
+ const walletClient = createWalletClient({
81
+ account,
82
+ chain: sepolia,
83
+ transport: http()
84
+ })
85
+
86
+ // 2. Fetch Available Currencies
87
+ const currencies = await getAvailableDhaliCurrencies()
88
+ const sepoliaUsdc = currencies.find(c => c.network === "SEPOLIA" && c.code === "USDC")
89
+
90
+ // 3. Instantiate Manager with Dynamic Config
91
+ const manager = DhaliChannelManager.evm(
92
+ walletClient,
93
+ publicClient,
94
+ sepoliaUsdc
95
+ )
96
+
97
+ // 4. Generate Claim
98
+ let token;
99
+ try {
100
+ token = await manager.getAuthToken(1000000); // 1.00 USDC
101
+ } catch (error) {
102
+ if (error.name === "ChannelNotFound") {
103
+ await manager.deposit(1000000); // Deposit 1.00 USDC
104
+ token = await manager.getAuthToken(1000000);
105
+ } else {
106
+ throw error;
107
+ }
91
108
  }
109
+ console.log('EVM Token:', token);
92
110
  }
93
- console.log('EVM Token:', token);
111
+
112
+ main();
94
113
  ```
95
114
 
96
115
  ---
@@ -104,26 +123,64 @@ const url = `https://xrplcluster.dhali.io?payment-claim=${token}`
104
123
  const response = await fetch(url, { method: 'POST', body: ... })
105
124
  ```
106
125
 
126
+ ## Standardized x402 Payments
127
+
128
+ For APIs that follow the x402 standard, you may need to wrap your auth token with the payment requirement (retrieved from the `payment-required` header of a 402 response).
129
+
130
+ ```js
131
+ const { wrapAsX402PaymentPayload } = require('dhali-js');
132
+
133
+ async function main() {
134
+ // 1. Get your token as usual
135
+ const token = await manager.getAuthToken();
136
+
137
+ // 2. Get the payment requirement from the 'payment-required' header of a 402 response
138
+ const paymentRequirement = response.headers.get("payment-required");
139
+
140
+ // 3. Wrap into an x402 payload
141
+ const x402Payload = wrapAsX402PaymentPayload(token, paymentRequirement);
142
+
143
+ // 4. Use 'x402Payload' in the 'Payment' header
144
+ }
145
+
146
+ main();
147
+ ```
148
+
107
149
  ---
108
150
 
109
151
  ## API Reference
110
152
 
111
- ### `DhaliChannelManager`
153
+ ### `DhaliChannelManager` (Factory)
154
+
155
+ * `.xrpl(wallet, client, currency)`: Returns `DhaliXrplChannelManager`.
156
+ * `.evm(walletClient, publicClient, currency)`: Returns `DhaliEthChannelManager`.
112
157
 
113
- * `.xrpl(wallet, client, protocol, currency)`: Returns `DhaliXrplChannelManager`.
114
- * `.evm(signer, provider, protocol, currency)`: Returns `DhaliEthChannelManager`.
158
+ ### `DhaliEthChannelManager` & `DhaliXrplChannelManager`
159
+
160
+ Both managers provide the following core methods:
161
+
162
+ * `async deposit(amount)`: Deposits funds into a payment channel. For EVM/XRPL, `amount` is in base units (wei/drops, etc). If no channel exists, it creates one; if it exists, it funds it.
163
+ * `async getAuthToken(amount = null)`: Generates a base64-encoded payment claim. If `amount` is provided, the claim is authorized up to that value. Defaults to total channel capacity if `amount` is `null`.
115
164
 
116
165
  ### `getAvailableDhaliCurrencies()`
117
166
 
118
- Returns a Promise resolving to:
167
+ Returns a Promise resolving to an array of `Currency` objects:
119
168
  ```js
120
- {
121
- "SEPOLIA": {
122
- "USDC": { currency: ..., destinationAddress: ... },
123
- ...
124
- },
169
+ [
170
+ { network: "SEPOLIA", code: "USDC", scale: 6, tokenAddress: "..." },
125
171
  ...
126
- }
172
+ ]
127
173
  ```
128
174
 
175
+ ---
176
+
177
+ ## Utilities
178
+
179
+ ### `wrapAsX402PaymentPayload(token, paymentRequirement)`
180
+
181
+ Wraps an auth token and a payment requirement (retrieved from a 402 response header) into a base64-encoded x402-compliant payload.
182
+
183
+ * **`token`**: The base64-encoded claim generated by `getAuthToken()`.
184
+ * **`paymentRequirement`**: The base64-encoded requirement string from the `payment-required` header.
185
+
129
186
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dhali-js",
3
- "version": "2.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "A JavaScript library for managing XRPL payment channels and generating auth tokens for Dhali APIs",
5
5
  "main": "src/index.js",
6
6
  "type": "commonjs",
@@ -16,8 +16,8 @@
16
16
  ],
17
17
  "license": "MIT",
18
18
  "dependencies": {
19
- "ethers": "^6.0.0",
20
19
  "ripple-keypairs": "^2.0.0",
20
+ "viem": "^2.23.5",
21
21
  "xrpl": "^4.0.0"
22
22
  },
23
23
  "devDependencies": {
@@ -1,5 +1,6 @@
1
1
  class Currency {
2
- constructor(code, scale, tokenAddress = null) {
2
+ constructor(network, code, scale, tokenAddress = null) {
3
+ this.network = network;
3
4
  this.code = code;
4
5
  this.scale = scale;
5
6
  this.tokenAddress = tokenAddress;
@@ -5,30 +5,27 @@ const DhaliChannelManager = {
5
5
  /**
6
6
  * @param {import("xrpl").Wallet} wallet
7
7
  * @param {import("xrpl").Client} client
8
- * @param {string} protocol
9
8
  * @param {import("./Currency")} currency
10
9
  * @param {typeof fetch} [httpClient] - Injected HTTP client
11
10
  * @param {object} [publicConfig]
12
11
  * @returns {DhaliXrplChannelManager}
13
12
  */
14
- xrpl: (wallet, client, protocol, currency, httpClient, publicConfig) => {
15
- return new DhaliXrplChannelManager(wallet, client, protocol, currency, httpClient, publicConfig);
13
+ xrpl: (wallet, client, currency, httpClient, publicConfig) => {
14
+ return new DhaliXrplChannelManager(wallet, client, currency, httpClient, publicConfig);
16
15
  },
17
16
 
18
17
  /**
19
- * @param {import("ethers").Signer} signer
20
- * @param {import("ethers").Provider} provider
21
- * @param {string} protocol
18
+ * @param {import("viem").WalletClient} walletClient
19
+ * @param {import("viem").PublicClient} publicClient
22
20
  * @param {import("./Currency")} currency
23
21
  * @param {typeof fetch} [httpClient] - Injected HTTP client
24
22
  * @param {object} [publicConfig]
25
23
  * @returns {DhaliEthChannelManager}
26
24
  */
27
- evm: (signer, provider, protocol, currency, httpClient, publicConfig) => {
25
+ evm: (walletClient, publicClient, currency, httpClient, publicConfig) => {
28
26
  return new DhaliEthChannelManager(
29
- signer,
30
- provider,
31
- protocol,
27
+ walletClient,
28
+ publicClient,
32
29
  currency,
33
30
  httpClient,
34
31
  publicConfig