@4mica/sdk 1.1.0 → 1.2.0

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.
Files changed (2) hide show
  1. package/README.md +85 -52
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -25,12 +25,30 @@ yarn add @4mica/sdk
25
25
 
26
26
  Node.js 18+ is required.
27
27
 
28
+ ## Networks
29
+
30
+ | Shorthand | CAIP-2 | Core API URL |
31
+ | ------------------ | ----------------- | ----------------------------------------- |
32
+ | `ethereum-sepolia` | `eip155:11155111` | `https://ethereum.sepolia.api.4mica.xyz/` |
33
+ | `base-sepolia` | `eip155:84532` | `https://base.sepolia.api.4mica.xyz/` |
34
+
35
+ The default network is Ethereum Sepolia. Use `.network()` or the `4MICA_NETWORK` environment
36
+ variable to switch networks.
37
+
38
+ ```ts
39
+ import { NETWORKS } from '@4mica/sdk';
40
+
41
+ console.log(NETWORKS['base-sepolia'].caip2); // "eip155:84532"
42
+ console.log(NETWORKS['base-sepolia'].rpcUrl); // "https://base.sepolia.api.4mica.xyz/"
43
+ ```
44
+
28
45
  ## Initialization and Configuration
29
46
 
30
47
  The SDK requires a signing key and can use sensible defaults for the rest:
31
48
 
32
49
  - `walletPrivateKey` (**required** unless `signer` is provided): private key used for signing
33
- - `rpcUrl` (optional): URL of the 4Mica core RPC server. Defaults to `https://api.4mica.xyz/`.
50
+ - `network` (optional): select a network by shorthand or CAIP-2 id. Defaults to `ethereum-sepolia`.
51
+ - `rpcUrl` (optional): override the core API URL directly (for self-hosted deployments).
34
52
  - `ethereumHttpRpcUrl` (optional): Ethereum JSON-RPC endpoint; fetched from core if omitted
35
53
  - `contractAddress` (optional): Core4Mica contract address; fetched from core if omitted
36
54
  - `adminApiKey` (optional): API key for admin RPCs
@@ -45,12 +63,12 @@ The SDK requires a signing key and can use sensible defaults for the rest:
45
63
  ### 1) Using ConfigBuilder
46
64
 
47
65
  ```ts
48
- import { Client, ConfigBuilder } from "@4mica/sdk";
66
+ import { Client, ConfigBuilder } from '@4mica/sdk';
49
67
 
50
68
  async function main() {
51
69
  const cfg = new ConfigBuilder()
52
- .rpcUrl("https://api.4mica.xyz/")
53
- .walletPrivateKey("0x...")
70
+ .network('base-sepolia') // or "ethereum-sepolia" (default)
71
+ .walletPrivateKey('0x...')
54
72
  .build();
55
73
 
56
74
  const client = await Client.new(cfg);
@@ -68,12 +86,14 @@ Set environment variables (example `.env`):
68
86
 
69
87
  ```bash
70
88
  4MICA_WALLET_PRIVATE_KEY="0x..."
71
- 4MICA_RPC_URL="https://api.4mica.xyz/"
89
+ 4MICA_NETWORK="base-sepolia" # shorthand or CAIP-2 id
90
+ # or override URL directly:
91
+ # 4MICA_RPC_URL="https://base.sepolia.api.4mica.xyz/"
72
92
  4MICA_ETHEREUM_HTTP_RPC_URL="http://localhost:8545"
73
93
  4MICA_CONTRACT_ADDRESS="0x..."
74
94
  4MICA_ADMIN_API_KEY="ak_..."
75
95
  4MICA_BEARER_TOKEN="Bearer <access_token>"
76
- 4MICA_AUTH_URL="https://api.4mica.xyz/"
96
+ 4MICA_AUTH_URL="https://ethereum.sepolia.api.4mica.xyz/"
77
97
  4MICA_AUTH_REFRESH_MARGIN_SECS="60"
78
98
  ```
79
99
 
@@ -81,13 +101,13 @@ If you want to set them inline for a single command, use `env` since most shells
81
101
  variable names that start with a digit:
82
102
 
83
103
  ```bash
84
- env 4MICA_WALLET_PRIVATE_KEY="0x..." 4MICA_RPC_URL="https://api.4mica.xyz/" node app.js
104
+ env 4MICA_WALLET_PRIVATE_KEY="0x..." 4MICA_NETWORK="base-sepolia" node app.js
85
105
  ```
86
106
 
87
107
  Then in code:
88
108
 
89
109
  ```ts
90
- import { Client, ConfigBuilder } from "@4mica/sdk";
110
+ import { Client, ConfigBuilder } from '@4mica/sdk';
91
111
 
92
112
  const cfg = new ConfigBuilder().fromEnv().build();
93
113
  const client = await Client.new(cfg);
@@ -100,8 +120,8 @@ If you want to integrate with a custom signer (hardware wallet, remote signer, e
100
120
  SIWE auth.
101
121
 
102
122
  ```ts
103
- import { Client, ConfigBuilder } from "@4mica/sdk";
104
- import { privateKeyToAccount } from "viem/accounts";
123
+ import { Client, ConfigBuilder } from '@4mica/sdk';
124
+ import { privateKeyToAccount } from 'viem/accounts';
105
125
 
106
126
  const signer = privateKeyToAccount(process.env.PAYER_KEY as `0x${string}`);
107
127
  const cfg = new ConfigBuilder().signer(signer).build();
@@ -113,11 +133,11 @@ const client = await Client.new(cfg);
113
133
  Enable automatic SIWE auth refresh, or pass a static bearer token:
114
134
 
115
135
  ```ts
116
- import { Client, ConfigBuilder } from "@4mica/sdk";
136
+ import { Client, ConfigBuilder } from '@4mica/sdk';
117
137
 
118
138
  const cfg = new ConfigBuilder()
119
- .walletPrivateKey("0x...")
120
- .rpcUrl("https://api.4mica.xyz/")
139
+ .walletPrivateKey('0x...')
140
+ .rpcUrl('https://api.4mica.xyz/')
121
141
  .enableAuth()
122
142
  .build();
123
143
 
@@ -129,8 +149,8 @@ Or use a static token:
129
149
 
130
150
  ```ts
131
151
  const cfg = new ConfigBuilder()
132
- .walletPrivateKey("0x...")
133
- .bearerToken("Bearer <access_token>")
152
+ .walletPrivateKey('0x...')
153
+ .bearerToken('Bearer <access_token>')
134
154
  .build();
135
155
  ```
136
156
 
@@ -147,6 +167,7 @@ The SDK exposes three main entry points:
147
167
  ### End-to-end Example (Base Sepolia + x402 v2)
148
168
 
149
169
  See `examples/base-sepolia-x402-facilitator-e2e.ts` for a full flow in the `examples` folder:
170
+
150
171
  - deposit collateral
151
172
  - create/get a tab via facilitator
152
173
  - issue and verify V1 + V2 guarantees
@@ -169,6 +190,7 @@ X-PAYMENT header (and optional `/settle` call) that the facilitator will accept.
169
190
  #### What the SDK expects from `paymentRequirements`
170
191
 
171
192
  At minimum you need:
193
+
172
194
  - `scheme` and `network` (scheme must include `4mica`, e.g. `4mica-credit`)
173
195
  - `payTo` (recipient address), `asset`, and `maxAmountRequired` (v1) or `amount` (v2)
174
196
  - `extra.tabEndpoint` for tab resolution
@@ -180,8 +202,8 @@ At minimum you need:
180
202
  Version 1 returns payment requirements in the JSON response body:
181
203
 
182
204
  ```ts
183
- import { Client, ConfigBuilder, X402Flow } from "@4mica/sdk";
184
- import type { PaymentRequirementsV1 } from "@4mica/sdk";
205
+ import { Client, ConfigBuilder, X402Flow } from '@4mica/sdk';
206
+ import type { PaymentRequirementsV1 } from '@4mica/sdk';
185
207
 
186
208
  type ResourceResponse = {
187
209
  x402Version: number;
@@ -189,23 +211,23 @@ type ResourceResponse = {
189
211
  error?: string;
190
212
  };
191
213
 
192
- const cfg = new ConfigBuilder().walletPrivateKey("0x...").build();
214
+ const cfg = new ConfigBuilder().walletPrivateKey('0x...').build();
193
215
  const client = await Client.new(cfg);
194
216
  const flow = X402Flow.fromClient(client);
195
217
 
196
218
  // 1) GET the protected endpoint and parse JSON body
197
- const res = await fetch("https://resource-url/resource");
219
+ const res = await fetch('https://resource-url/resource');
198
220
  const body = (await res.json()) as ResourceResponse;
199
221
 
200
222
  // 2) Select a payment option
201
223
  const requirements = body.accepts[0];
202
224
 
203
225
  // 3) Build the X-PAYMENT header with the SDK
204
- const payment = await flow.signPayment(requirements, "0xUser");
226
+ const payment = await flow.signPayment(requirements, '0xUser');
205
227
 
206
228
  // 4) Call the protected resource with the header
207
- await fetch("https://resource-url/resource", {
208
- headers: { "X-PAYMENT": payment.header },
229
+ await fetch('https://resource-url/resource', {
230
+ headers: { 'X-PAYMENT': payment.header },
209
231
  });
210
232
 
211
233
  await client.aclose();
@@ -216,31 +238,31 @@ await client.aclose();
216
238
  Version 2 uses the `payment-required` header (base64-encoded) instead of a JSON response body:
217
239
 
218
240
  ```ts
219
- import { Client, ConfigBuilder, X402Flow } from "@4mica/sdk";
220
- import type { X402PaymentRequired, PaymentRequirementsV2 } from "@4mica/sdk";
241
+ import { Client, ConfigBuilder, X402Flow } from '@4mica/sdk';
242
+ import type { X402PaymentRequired, PaymentRequirementsV2 } from '@4mica/sdk';
221
243
 
222
- const cfg = new ConfigBuilder().walletPrivateKey("0x...").build();
244
+ const cfg = new ConfigBuilder().walletPrivateKey('0x...').build();
223
245
  const client = await Client.new(cfg);
224
246
  const flow = X402Flow.fromClient(client);
225
247
 
226
248
  // 1) GET the protected endpoint and extract payment-required header
227
- const res = await fetch("https://resource-url/resource");
228
- const header = res.headers.get("payment-required");
229
- if (!header) throw new Error("Missing payment-required header");
249
+ const res = await fetch('https://resource-url/resource');
250
+ const header = res.headers.get('payment-required');
251
+ if (!header) throw new Error('Missing payment-required header');
230
252
 
231
253
  // 2) Decode the header
232
- const decoded = Buffer.from(header, "base64").toString("utf8");
254
+ const decoded = Buffer.from(header, 'base64').toString('utf8');
233
255
  const paymentRequired = JSON.parse(decoded) as X402PaymentRequired;
234
256
 
235
257
  // 3) Select a payment option
236
258
  const accepted = paymentRequired.accepts[0] as PaymentRequirementsV2;
237
259
 
238
260
  // 4) Build the PAYMENT-SIGNATURE header with the SDK
239
- const signed = await flow.signPaymentV2(paymentRequired, accepted, "0xUser");
261
+ const signed = await flow.signPaymentV2(paymentRequired, accepted, '0xUser');
240
262
 
241
263
  // 5) Call the protected resource with the header
242
- await fetch("https://resource-url/resource", {
243
- headers: { "PAYMENT-SIGNATURE": signed.header },
264
+ await fetch('https://resource-url/resource', {
265
+ headers: { 'PAYMENT-SIGNATURE': signed.header },
244
266
  });
245
267
 
246
268
  await client.aclose();
@@ -252,8 +274,8 @@ If your resource server proxies to the facilitator, you can reuse the SDK to set
252
274
  verifying:
253
275
 
254
276
  ```ts
255
- import { Client, ConfigBuilder, X402Flow } from "@4mica/sdk";
256
- import type { PaymentRequirementsV1, X402SignedPayment } from "@4mica/sdk";
277
+ import { Client, ConfigBuilder, X402Flow } from '@4mica/sdk';
278
+ import type { PaymentRequirementsV1, X402SignedPayment } from '@4mica/sdk';
257
279
 
258
280
  async function settle(
259
281
  facilitatorUrl: string,
@@ -266,13 +288,14 @@ async function settle(
266
288
  const flow = X402Flow.fromClient(core);
267
289
 
268
290
  const settled = await flow.settlePayment(payment, paymentRequirements, facilitatorUrl);
269
- console.log("settlement result:", settled.settlement);
291
+ console.log('settlement result:', settled.settlement);
270
292
 
271
293
  await core.aclose();
272
294
  }
273
295
  ```
274
296
 
275
297
  Notes:
298
+
276
299
  - `signPayment` and `signPaymentV2` always use EIP-712 signing and will error if the scheme is not 4mica.
277
300
  - `UserClient.signPayment` supports `SigningScheme.EIP712` (default) and `SigningScheme.EIP191`.
278
301
  - `settlePayment` only hits `/settle`; resource servers should still call `/verify` first when enforcing access.
@@ -331,11 +354,17 @@ import {
331
354
  computeValidationSubjectHash,
332
355
  computeValidationRequestHash,
333
356
  SigningScheme,
334
- } from "@4mica/sdk";
357
+ } from '@4mica/sdk';
335
358
 
336
359
  // 1) Build base V1 claims first
337
360
  const baseClaims = PaymentGuaranteeRequestClaims.new(
338
- userAddress, recipientAddress, tabId, amount, timestamp, erc20Token, reqId
361
+ userAddress,
362
+ recipientAddress,
363
+ tabId,
364
+ amount,
365
+ timestamp,
366
+ erc20Token,
367
+ reqId
339
368
  );
340
369
 
341
370
  // 2) Compute canonical hashes
@@ -343,14 +372,14 @@ const validationSubjectHash = computeValidationSubjectHash(baseClaims);
343
372
 
344
373
  const partialV2 = new PaymentGuaranteeRequestClaimsV2({
345
374
  ...baseClaims,
346
- validationRegistryAddress: "0x...",
347
- validationRequestHash: "0x" + "00".repeat(32), // placeholder
375
+ validationRegistryAddress: '0x...',
376
+ validationRequestHash: '0x' + '00'.repeat(32), // placeholder
348
377
  validationChainId: 1,
349
- validatorAddress: "0x...",
378
+ validatorAddress: '0x...',
350
379
  validatorAgentId: 1n,
351
- minValidationScore: 80, // 1–100
380
+ minValidationScore: 80, // 1–100
352
381
  validationSubjectHash,
353
- requiredValidationTag: "my-tag",
382
+ requiredValidationTag: 'my-tag',
354
383
  });
355
384
 
356
385
  const validationRequestHash = computeValidationRequestHash(partialV2);
@@ -367,21 +396,25 @@ All SDK errors extend `FourMicaError`. Import individual error classes to distin
367
396
 
368
397
  ```ts
369
398
  import {
370
- ConfigError, // invalid ConfigBuilder input
371
- RpcError, // 4Mica core service error (has .status and .body)
372
- SigningError, // signing scheme unsupported or address mismatch
373
- ContractError, // on-chain call failed or unexpected result
374
- VerificationError, // BLS certificate decode/domain mismatch
375
- X402Error, // x402 flow error (bad scheme, tab resolution, settlement)
376
- AuthError, // base class for all auth errors
399
+ ConfigError, // invalid ConfigBuilder input
400
+ RpcError, // 4Mica core service error (has .status and .body)
401
+ SigningError, // signing scheme unsupported or address mismatch
402
+ ContractError, // on-chain call failed or unexpected result
403
+ VerificationError, // BLS certificate decode/domain mismatch
404
+ X402Error, // x402 flow error (bad scheme, tab resolution, settlement)
405
+ AuthError, // base class for all auth errors
377
406
  AuthMissingConfigError, // auth not configured when login() is called
378
- } from "@4mica/sdk";
407
+ } from '@4mica/sdk';
379
408
 
380
409
  try {
381
410
  await client.recipient.remunerate(cert);
382
411
  } catch (err) {
383
- if (err instanceof VerificationError) { /* bad cert */ }
384
- if (err instanceof ContractError) { /* on-chain failure */ }
412
+ if (err instanceof VerificationError) {
413
+ /* bad cert */
414
+ }
415
+ if (err instanceof ContractError) {
416
+ /* on-chain failure */
417
+ }
385
418
  }
386
419
  ```
387
420
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4mica/sdk",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "TypeScript SDK for interacting with the 4Mica payment network",
5
5
  "license": "MIT",
6
6
  "repository": {