@opencardsdk/sdk 0.1.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.
- package/README.md +139 -0
- package/dist/client.d.ts +43 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +143 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +55 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +121 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/x402.d.ts +37 -0
- package/dist/x402.d.ts.map +1 -0
- package/dist/x402.js +118 -0
- package/dist/x402.js.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# @opencard/sdk
|
|
2
|
+
|
|
3
|
+
Client SDK for OpenCard — create virtual cards with USDC payments via the x402 protocol.
|
|
4
|
+
|
|
5
|
+
Wraps the raw x402 flow (402 → parse challenge → pay USDC → retry with proof) into one-liner methods.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @opencard/sdk viem
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { OpenCardClient } from '@opencard/sdk';
|
|
17
|
+
|
|
18
|
+
const client = new OpenCardClient({
|
|
19
|
+
privateKey: '0x...', // or pass a viem WalletClient
|
|
20
|
+
baseUrl: 'https://api.opencard.com',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// One line — SDK handles payment automatically
|
|
24
|
+
const card = await client.createCard({
|
|
25
|
+
amount: 10, // $10 tier
|
|
26
|
+
nameOnCard: 'AI AGENT',
|
|
27
|
+
email: 'agent@example.com',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
console.log(card.cardDetails); // { cardNumber, cvv, expiry, ... }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## API
|
|
34
|
+
|
|
35
|
+
### `new OpenCardClient(config)`
|
|
36
|
+
|
|
37
|
+
| Option | Type | Required | Description |
|
|
38
|
+
|--------|------|----------|-------------|
|
|
39
|
+
| `privateKey` | `0x${string}` | One of | Hex private key — SDK creates wallet internally |
|
|
40
|
+
| `walletClient` | `WalletClient` | One of | Your own viem WalletClient (takes precedence) |
|
|
41
|
+
| `baseUrl` | `string` | No | API URL (default: `https://api.opencard.com`) |
|
|
42
|
+
| `rpcUrl` | `string` | No | Base RPC URL (default: public RPC) |
|
|
43
|
+
| `timeout` | `number` | No | Request timeout in ms (default: 60000) |
|
|
44
|
+
|
|
45
|
+
### `client.createCard(params): Promise<CardResult>`
|
|
46
|
+
|
|
47
|
+
Create a virtual card. Pays USDC automatically.
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
const result = await client.createCard({
|
|
51
|
+
amount: 50, // 10 | 25 | 50 | 100 | 200 | 500
|
|
52
|
+
nameOnCard: 'AI AGENT',
|
|
53
|
+
email: 'agent@example.com',
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `client.fundCard(params): Promise<FundResult>`
|
|
58
|
+
|
|
59
|
+
Fund an existing card.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const result = await client.fundCard({
|
|
63
|
+
amount: 25,
|
|
64
|
+
cardId: 'card-uuid',
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### `client.getTiers(): Promise<TiersResponse>`
|
|
69
|
+
|
|
70
|
+
Get pricing tiers and fee breakdown (no payment required).
|
|
71
|
+
|
|
72
|
+
### `client.health(): Promise<{ status: string }>`
|
|
73
|
+
|
|
74
|
+
Check if the OpenCard API is reachable.
|
|
75
|
+
|
|
76
|
+
### `client.address: 0x${string}`
|
|
77
|
+
|
|
78
|
+
The wallet address being used for payments.
|
|
79
|
+
|
|
80
|
+
## Error Handling
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import {
|
|
84
|
+
OpenCardClient,
|
|
85
|
+
InsufficientBalanceError,
|
|
86
|
+
PaymentError,
|
|
87
|
+
ApiError,
|
|
88
|
+
TimeoutError,
|
|
89
|
+
} from '@opencard/sdk';
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const card = await client.createCard({ ... });
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (error instanceof InsufficientBalanceError) {
|
|
95
|
+
console.log(`Need ${error.required}, have ${error.available}`);
|
|
96
|
+
} else if (error instanceof PaymentError) {
|
|
97
|
+
console.log(`Payment failed: ${error.message}, tx: ${error.txHash}`);
|
|
98
|
+
} else if (error instanceof ApiError) {
|
|
99
|
+
console.log(`Server error ${error.status}:`, error.body);
|
|
100
|
+
} else if (error instanceof TimeoutError) {
|
|
101
|
+
console.log('Request timed out');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Advanced: Low-Level x402 Utilities
|
|
107
|
+
|
|
108
|
+
For custom integrations, the x402 protocol helpers are exported directly:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import {
|
|
112
|
+
parseChallenge,
|
|
113
|
+
checkBalance,
|
|
114
|
+
executePayment,
|
|
115
|
+
buildPaymentProof,
|
|
116
|
+
handleX402Payment,
|
|
117
|
+
} from '@opencard/sdk';
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## How It Works
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
Your Code SDK OpenCard API Base Chain
|
|
124
|
+
| | | |
|
|
125
|
+
|-- createCard ->| | |
|
|
126
|
+
| |--- POST /create/tier -->| |
|
|
127
|
+
| |<-- 402 + challenge -----| |
|
|
128
|
+
| | | |
|
|
129
|
+
| |--- USDC.transfer() -----|-------- tx ------->|
|
|
130
|
+
| |<-- txHash --------------|-------- receipt ---|
|
|
131
|
+
| | | |
|
|
132
|
+
| |--- POST + X-Payment --->| |
|
|
133
|
+
| |<-- 201 + card details --| |
|
|
134
|
+
|<- CardResult --| | |
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { OpenCardConfig, CreateCardParams, FundCardParams, CardResult, FundResult, TiersResponse } from "./types.js";
|
|
2
|
+
export declare class OpenCardClient {
|
|
3
|
+
private walletClient;
|
|
4
|
+
private baseUrl;
|
|
5
|
+
private timeout;
|
|
6
|
+
constructor(config: OpenCardConfig);
|
|
7
|
+
/** The wallet address used for payments */
|
|
8
|
+
get address(): `0x${string}`;
|
|
9
|
+
/**
|
|
10
|
+
* Create a virtual card with automatic USDC payment.
|
|
11
|
+
*
|
|
12
|
+
* Handles the full x402 flow:
|
|
13
|
+
* 1. Sends request → gets 402 with payment requirements
|
|
14
|
+
* 2. Executes USDC transfer on Base
|
|
15
|
+
* 3. Retries with payment proof
|
|
16
|
+
* 4. Returns card details
|
|
17
|
+
*/
|
|
18
|
+
createCard(params: CreateCardParams): Promise<CardResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Fund an existing card with automatic USDC payment.
|
|
21
|
+
*/
|
|
22
|
+
fundCard(params: FundCardParams): Promise<FundResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Get available tiers and pricing breakdown (no payment required).
|
|
25
|
+
*/
|
|
26
|
+
getTiers(): Promise<TiersResponse>;
|
|
27
|
+
/**
|
|
28
|
+
* Health check — verify the server is reachable.
|
|
29
|
+
*/
|
|
30
|
+
health(): Promise<{
|
|
31
|
+
status: string;
|
|
32
|
+
}>;
|
|
33
|
+
/**
|
|
34
|
+
* Execute a paid request with automatic x402 handling.
|
|
35
|
+
*
|
|
36
|
+
* 1. POST to endpoint → expect 402
|
|
37
|
+
* 2. Parse challenge → execute USDC payment → build proof
|
|
38
|
+
* 3. Retry POST with X-Payment header
|
|
39
|
+
*/
|
|
40
|
+
private paidRequest;
|
|
41
|
+
private fetch;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,YAAY,CAAC;AAOpB,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAA0C;IAC9D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,cAAc;IAqBlC,2CAA2C;IAC3C,IAAI,OAAO,IAAI,KAAK,MAAM,EAAE,CAE3B;IAID;;;;;;;;OAQG;IACG,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAU/D;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAU3D;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,aAAa,CAAC;IAgBxC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAO3C;;;;;;OAMG;YACW,WAAW;YAqDX,KAAK;CAepB"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { createWalletClient, http, } from "viem";
|
|
2
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
3
|
+
import { base } from "viem/chains";
|
|
4
|
+
import { handleX402Payment } from "./x402.js";
|
|
5
|
+
import { ConfigError, ApiError, TimeoutError } from "./errors.js";
|
|
6
|
+
const DEFAULT_BASE_URL = "https://api.opencard.com";
|
|
7
|
+
const DEFAULT_TIMEOUT = 60_000;
|
|
8
|
+
export class OpenCardClient {
|
|
9
|
+
walletClient;
|
|
10
|
+
baseUrl;
|
|
11
|
+
timeout;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
14
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
15
|
+
if (config.walletClient) {
|
|
16
|
+
if (!config.walletClient.account) {
|
|
17
|
+
throw new ConfigError("walletClient must have an account attached");
|
|
18
|
+
}
|
|
19
|
+
this.walletClient = config.walletClient;
|
|
20
|
+
}
|
|
21
|
+
else if (config.privateKey) {
|
|
22
|
+
const account = privateKeyToAccount(config.privateKey);
|
|
23
|
+
this.walletClient = createWalletClient({
|
|
24
|
+
account,
|
|
25
|
+
chain: base,
|
|
26
|
+
transport: http(config.rpcUrl),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
throw new ConfigError("Provide either privateKey or walletClient");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** The wallet address used for payments */
|
|
34
|
+
get address() {
|
|
35
|
+
return this.walletClient.account.address;
|
|
36
|
+
}
|
|
37
|
+
// ── Card Creation ───────────────────────────────────────────────────
|
|
38
|
+
/**
|
|
39
|
+
* Create a virtual card with automatic USDC payment.
|
|
40
|
+
*
|
|
41
|
+
* Handles the full x402 flow:
|
|
42
|
+
* 1. Sends request → gets 402 with payment requirements
|
|
43
|
+
* 2. Executes USDC transfer on Base
|
|
44
|
+
* 3. Retries with payment proof
|
|
45
|
+
* 4. Returns card details
|
|
46
|
+
*/
|
|
47
|
+
async createCard(params) {
|
|
48
|
+
const { amount, nameOnCard, email } = params;
|
|
49
|
+
const endpoint = `${this.baseUrl}/cards/create/tier/${amount}`;
|
|
50
|
+
const body = JSON.stringify({ nameOnCard, email });
|
|
51
|
+
return this.paidRequest(endpoint, body);
|
|
52
|
+
}
|
|
53
|
+
// ── Card Funding ────────────────────────────────────────────────────
|
|
54
|
+
/**
|
|
55
|
+
* Fund an existing card with automatic USDC payment.
|
|
56
|
+
*/
|
|
57
|
+
async fundCard(params) {
|
|
58
|
+
const { amount, cardId } = params;
|
|
59
|
+
const endpoint = `${this.baseUrl}/cards/fund/tier/${amount}`;
|
|
60
|
+
const body = JSON.stringify({ cardId });
|
|
61
|
+
return this.paidRequest(endpoint, body);
|
|
62
|
+
}
|
|
63
|
+
// ── Pricing ─────────────────────────────────────────────────────────
|
|
64
|
+
/**
|
|
65
|
+
* Get available tiers and pricing breakdown (no payment required).
|
|
66
|
+
*/
|
|
67
|
+
async getTiers() {
|
|
68
|
+
const res = await this.fetch(`${this.baseUrl}/cards/tiers`, {
|
|
69
|
+
method: "GET",
|
|
70
|
+
});
|
|
71
|
+
if (!res.ok) {
|
|
72
|
+
throw new ApiError(`Failed to fetch tiers: ${res.statusText}`, res.status, await res.json().catch(() => null));
|
|
73
|
+
}
|
|
74
|
+
return res.json();
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Health check — verify the server is reachable.
|
|
78
|
+
*/
|
|
79
|
+
async health() {
|
|
80
|
+
const res = await this.fetch(`${this.baseUrl}/health`, { method: "GET" });
|
|
81
|
+
return res.json();
|
|
82
|
+
}
|
|
83
|
+
// ── Internal: x402 Payment Flow ─────────────────────────────────────
|
|
84
|
+
/**
|
|
85
|
+
* Execute a paid request with automatic x402 handling.
|
|
86
|
+
*
|
|
87
|
+
* 1. POST to endpoint → expect 402
|
|
88
|
+
* 2. Parse challenge → execute USDC payment → build proof
|
|
89
|
+
* 3. Retry POST with X-Payment header
|
|
90
|
+
*/
|
|
91
|
+
async paidRequest(endpoint, body) {
|
|
92
|
+
// Step 1: Initial request — expect 402
|
|
93
|
+
const initialRes = await this.fetch(endpoint, {
|
|
94
|
+
method: "POST",
|
|
95
|
+
headers: { "Content-Type": "application/json" },
|
|
96
|
+
body,
|
|
97
|
+
});
|
|
98
|
+
// If server doesn't return 402, handle accordingly
|
|
99
|
+
if (initialRes.status !== 402) {
|
|
100
|
+
if (initialRes.ok) {
|
|
101
|
+
// No payment needed (shouldn't happen but handle gracefully)
|
|
102
|
+
return initialRes.json();
|
|
103
|
+
}
|
|
104
|
+
const errorBody = await initialRes.json().catch(() => null);
|
|
105
|
+
throw new ApiError(`Unexpected response: ${initialRes.status} ${initialRes.statusText}`, initialRes.status, errorBody);
|
|
106
|
+
}
|
|
107
|
+
// Step 2: Parse 402, pay, get proof
|
|
108
|
+
const challengeBody = await initialRes.json();
|
|
109
|
+
const { header, txHash } = await handleX402Payment(this.walletClient, challengeBody);
|
|
110
|
+
// Step 3: Retry with payment proof
|
|
111
|
+
const paidRes = await this.fetch(endpoint, {
|
|
112
|
+
method: "POST",
|
|
113
|
+
headers: {
|
|
114
|
+
"Content-Type": "application/json",
|
|
115
|
+
"X-Payment": header,
|
|
116
|
+
},
|
|
117
|
+
body,
|
|
118
|
+
});
|
|
119
|
+
if (!paidRes.ok) {
|
|
120
|
+
const errorBody = await paidRes.json().catch(() => null);
|
|
121
|
+
throw new ApiError(`Request failed after payment (tx: ${txHash}): ${paidRes.status}`, paidRes.status, errorBody);
|
|
122
|
+
}
|
|
123
|
+
return paidRes.json();
|
|
124
|
+
}
|
|
125
|
+
// ── Internal: Fetch with timeout ────────────────────────────────────
|
|
126
|
+
async fetch(url, init) {
|
|
127
|
+
const controller = new AbortController();
|
|
128
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
129
|
+
try {
|
|
130
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
134
|
+
throw new TimeoutError(this.timeout);
|
|
135
|
+
}
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
clearTimeout(timer);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Base error for all OpenCard SDK errors */
|
|
2
|
+
export declare class OpenCardError extends Error {
|
|
3
|
+
readonly code: string;
|
|
4
|
+
constructor(message: string, code: string);
|
|
5
|
+
}
|
|
6
|
+
/** Configuration is invalid or missing */
|
|
7
|
+
export declare class ConfigError extends OpenCardError {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
10
|
+
/** Server returned 402 but payment failed */
|
|
11
|
+
export declare class PaymentError extends OpenCardError {
|
|
12
|
+
readonly txHash?: string;
|
|
13
|
+
constructor(message: string, options?: {
|
|
14
|
+
txHash?: string;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/** Insufficient USDC balance to cover the payment */
|
|
18
|
+
export declare class InsufficientBalanceError extends OpenCardError {
|
|
19
|
+
readonly required: bigint;
|
|
20
|
+
readonly available: bigint;
|
|
21
|
+
constructor(required: bigint, available: bigint);
|
|
22
|
+
}
|
|
23
|
+
/** Server returned a non-402 error */
|
|
24
|
+
export declare class ApiError extends OpenCardError {
|
|
25
|
+
readonly status: number;
|
|
26
|
+
readonly body?: unknown | undefined;
|
|
27
|
+
constructor(message: string, status: number, body?: unknown | undefined);
|
|
28
|
+
}
|
|
29
|
+
/** Request timed out */
|
|
30
|
+
export declare class TimeoutError extends OpenCardError {
|
|
31
|
+
constructor(ms: number);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,EAAE,MAAM;gBAD5B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM;CAK/B;AAED,0CAA0C;AAC1C,qBAAa,WAAY,SAAQ,aAAa;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED,6CAA6C;AAC7C,qBAAa,YAAa,SAAQ,aAAa;IAC7C,SAAgB,MAAM,CAAC,EAAE,MAAM,CAAC;gBAG9B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;CAMhC;AAED,qDAAqD;AACrD,qBAAa,wBAAyB,SAAQ,aAAa;aAEvC,QAAQ,EAAE,MAAM;aAChB,SAAS,EAAE,MAAM;gBADjB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM;CAQpC;AAED,sCAAsC;AACtC,qBAAa,QAAS,SAAQ,aAAa;aAGvB,MAAM,EAAE,MAAM;aACd,IAAI,CAAC,EAAE,OAAO;gBAF9B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,OAAO,YAAA;CAKjC;AAED,wBAAwB;AACxB,qBAAa,YAAa,SAAQ,aAAa;gBACjC,EAAE,EAAE,MAAM;CAIvB"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Base error for all OpenCard SDK errors */
|
|
2
|
+
export class OpenCardError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
constructor(message, code) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.name = "OpenCardError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Configuration is invalid or missing */
|
|
11
|
+
export class ConfigError extends OpenCardError {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message, "CONFIG_ERROR");
|
|
14
|
+
this.name = "ConfigError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Server returned 402 but payment failed */
|
|
18
|
+
export class PaymentError extends OpenCardError {
|
|
19
|
+
txHash;
|
|
20
|
+
constructor(message, options) {
|
|
21
|
+
super(message, "PAYMENT_ERROR");
|
|
22
|
+
this.name = "PaymentError";
|
|
23
|
+
this.txHash = options?.txHash;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Insufficient USDC balance to cover the payment */
|
|
27
|
+
export class InsufficientBalanceError extends OpenCardError {
|
|
28
|
+
required;
|
|
29
|
+
available;
|
|
30
|
+
constructor(required, available) {
|
|
31
|
+
super(`Insufficient USDC balance: need ${required} but have ${available} (amounts in 6-decimal units)`, "INSUFFICIENT_BALANCE");
|
|
32
|
+
this.required = required;
|
|
33
|
+
this.available = available;
|
|
34
|
+
this.name = "InsufficientBalanceError";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Server returned a non-402 error */
|
|
38
|
+
export class ApiError extends OpenCardError {
|
|
39
|
+
status;
|
|
40
|
+
body;
|
|
41
|
+
constructor(message, status, body) {
|
|
42
|
+
super(message, "API_ERROR");
|
|
43
|
+
this.status = status;
|
|
44
|
+
this.body = body;
|
|
45
|
+
this.name = "ApiError";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Request timed out */
|
|
49
|
+
export class TimeoutError extends OpenCardError {
|
|
50
|
+
constructor(ms) {
|
|
51
|
+
super(`Request timed out after ${ms}ms`, "TIMEOUT");
|
|
52
|
+
this.name = "TimeoutError";
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,MAAM,OAAO,aAAc,SAAQ,KAAK;IAGpB;IAFlB,YACE,OAAe,EACC,IAAY;QAE5B,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAAQ;QAG5B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,0CAA0C;AAC1C,MAAM,OAAO,WAAY,SAAQ,aAAa;IAC5C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,6CAA6C;AAC7C,MAAM,OAAO,YAAa,SAAQ,aAAa;IAC7B,MAAM,CAAU;IAEhC,YACE,OAAe,EACf,OAA6B;QAE7B,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;IAChC,CAAC;CACF;AAED,qDAAqD;AACrD,MAAM,OAAO,wBAAyB,SAAQ,aAAa;IAEvC;IACA;IAFlB,YACkB,QAAgB,EAChB,SAAiB;QAEjC,KAAK,CACH,mCAAmC,QAAQ,aAAa,SAAS,+BAA+B,EAChG,sBAAsB,CACvB,CAAC;QANc,aAAQ,GAAR,QAAQ,CAAQ;QAChB,cAAS,GAAT,SAAS,CAAQ;QAMjC,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AAED,sCAAsC;AACtC,MAAM,OAAO,QAAS,SAAQ,aAAa;IAGvB;IACA;IAHlB,YACE,OAAe,EACC,MAAc,EACd,IAAc;QAE9B,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAHZ,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAU;QAG9B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,wBAAwB;AACxB,MAAM,OAAO,YAAa,SAAQ,aAAa;IAC7C,YAAY,EAAU;QACpB,KAAK,CAAC,2BAA2B,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { OpenCardClient } from "./client.js";
|
|
2
|
+
export type { OpenCardConfig, CreateCardParams, FundCardParams, CardResult, FundResult, TiersResponse, TierBreakdown, X402Challenge, X402PaymentOption, X402PaymentProof, } from "./types.js";
|
|
3
|
+
export { OpenCardError, ConfigError, PaymentError, InsufficientBalanceError, ApiError, TimeoutError, } from "./errors.js";
|
|
4
|
+
export { parseChallenge, checkBalance, executePayment, buildPaymentProof, handleX402Payment, } from "./x402.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,wBAAwB,EACxB,QAAQ,EACR,YAAY,GACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,cAAc,EACd,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// ── Main Client ─────────────────────────────────────────────────────
|
|
2
|
+
export { OpenCardClient } from "./client.js";
|
|
3
|
+
// ── Errors ──────────────────────────────────────────────────────────
|
|
4
|
+
export { OpenCardError, ConfigError, PaymentError, InsufficientBalanceError, ApiError, TimeoutError, } from "./errors.js";
|
|
5
|
+
// ── Low-level x402 utilities (for advanced usage) ───────────────────
|
|
6
|
+
export { parseChallenge, checkBalance, executePayment, buildPaymentProof, handleX402Payment, } from "./x402.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAgB7C,uEAAuE;AACvE,OAAO,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,wBAAwB,EACxB,QAAQ,EACR,YAAY,GACb,MAAM,aAAa,CAAC;AAErB,uEAAuE;AACvE,OAAO,EACL,cAAc,EACd,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,WAAW,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { Account, Chain, Transport, WalletClient } from "viem";
|
|
2
|
+
export interface OpenCardConfig {
|
|
3
|
+
/** Private key (hex string with 0x prefix) — creates a wallet client internally */
|
|
4
|
+
privateKey?: `0x${string}`;
|
|
5
|
+
/** Or pass your own viem WalletClient (takes precedence over privateKey) */
|
|
6
|
+
walletClient?: WalletClient<Transport, Chain, Account>;
|
|
7
|
+
/** OpenCard API base URL (default: https://api.opencard.com) */
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
/** RPC URL for Base network (default: public Base RPC) */
|
|
10
|
+
rpcUrl?: string;
|
|
11
|
+
/** Request timeout in ms (default: 60000) */
|
|
12
|
+
timeout?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface CreateCardParams {
|
|
15
|
+
/** Tier amount in USD (10, 25, 50, 100, 200, 500) */
|
|
16
|
+
amount: number;
|
|
17
|
+
/** Name printed on the card (auto-uppercased) */
|
|
18
|
+
nameOnCard: string;
|
|
19
|
+
/** Email for card notifications */
|
|
20
|
+
email: string;
|
|
21
|
+
}
|
|
22
|
+
export interface FundCardParams {
|
|
23
|
+
/** Tier amount in USD (10, 25, 50, 100, 200, 500) */
|
|
24
|
+
amount: number;
|
|
25
|
+
/** Card ID to fund */
|
|
26
|
+
cardId: string;
|
|
27
|
+
}
|
|
28
|
+
export interface CardResult {
|
|
29
|
+
success: boolean;
|
|
30
|
+
card: {
|
|
31
|
+
cardId: string;
|
|
32
|
+
kripiCardId: string;
|
|
33
|
+
nameOnCard: string;
|
|
34
|
+
lastFour?: string;
|
|
35
|
+
balance: number | null;
|
|
36
|
+
status: string;
|
|
37
|
+
createdAt: string;
|
|
38
|
+
};
|
|
39
|
+
cardDetails?: {
|
|
40
|
+
cardNumber: string;
|
|
41
|
+
expiryMonth: number;
|
|
42
|
+
expiryYear: number;
|
|
43
|
+
cvv: string;
|
|
44
|
+
billingAddress: {
|
|
45
|
+
street: string;
|
|
46
|
+
city: string;
|
|
47
|
+
state: string;
|
|
48
|
+
zip: string;
|
|
49
|
+
country: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
payment: {
|
|
53
|
+
walletAddress: string;
|
|
54
|
+
txHash?: string;
|
|
55
|
+
amountUsd: number;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export interface FundResult {
|
|
59
|
+
success: boolean;
|
|
60
|
+
card: {
|
|
61
|
+
cardId: string;
|
|
62
|
+
newBalance?: number;
|
|
63
|
+
};
|
|
64
|
+
payment: {
|
|
65
|
+
walletAddress: string;
|
|
66
|
+
txHash?: string;
|
|
67
|
+
amountUsd: number;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export interface TierBreakdown {
|
|
71
|
+
loadAmount?: number;
|
|
72
|
+
fundAmount?: number;
|
|
73
|
+
totalCost: number;
|
|
74
|
+
endpoint: string;
|
|
75
|
+
breakdown: {
|
|
76
|
+
cardLoad?: number;
|
|
77
|
+
fundAmount?: number;
|
|
78
|
+
issuanceFee?: number;
|
|
79
|
+
topUpFee: number;
|
|
80
|
+
ourFee: number;
|
|
81
|
+
buffer?: number;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export interface TiersResponse {
|
|
85
|
+
creation: TierBreakdown[];
|
|
86
|
+
funding: TierBreakdown[];
|
|
87
|
+
}
|
|
88
|
+
export interface X402Challenge {
|
|
89
|
+
x402Version: number;
|
|
90
|
+
accepts: X402PaymentOption[];
|
|
91
|
+
error?: string;
|
|
92
|
+
}
|
|
93
|
+
export interface X402PaymentOption {
|
|
94
|
+
scheme: string;
|
|
95
|
+
network: string;
|
|
96
|
+
maxAmountRequired: string;
|
|
97
|
+
resource: string;
|
|
98
|
+
description: string;
|
|
99
|
+
mimeType: string;
|
|
100
|
+
payTo: `0x${string}`;
|
|
101
|
+
maxTimeoutSeconds: number;
|
|
102
|
+
asset: `0x${string}`;
|
|
103
|
+
extra?: Record<string, unknown>;
|
|
104
|
+
}
|
|
105
|
+
export interface X402PaymentProof {
|
|
106
|
+
scheme: string;
|
|
107
|
+
network: string;
|
|
108
|
+
payload: {
|
|
109
|
+
authorization: {
|
|
110
|
+
from: string;
|
|
111
|
+
to: string;
|
|
112
|
+
value: string;
|
|
113
|
+
validAfter: string;
|
|
114
|
+
validBefore: string;
|
|
115
|
+
nonce: string;
|
|
116
|
+
};
|
|
117
|
+
signature: string;
|
|
118
|
+
txHash: string;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/x402.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type Account, type Chain, type Transport, type WalletClient } from "viem";
|
|
2
|
+
import type { X402Challenge, X402PaymentOption } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Parse a 402 response body into a structured challenge.
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseChallenge(body: unknown): X402Challenge;
|
|
7
|
+
/**
|
|
8
|
+
* Check if the wallet has enough USDC to cover the payment.
|
|
9
|
+
* Uses a public client for read-only calls.
|
|
10
|
+
*/
|
|
11
|
+
export declare function checkBalance(walletClient: WalletClient<Transport, Chain, Account>, amount: bigint): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Execute USDC transfer on Base to the specified recipient.
|
|
14
|
+
* Returns the transaction hash.
|
|
15
|
+
*/
|
|
16
|
+
export declare function executePayment(walletClient: WalletClient<Transport, Chain, Account>, payTo: `0x${string}`, amount: bigint): Promise<`0x${string}`>;
|
|
17
|
+
/**
|
|
18
|
+
* Construct the x402 payment proof from the completed transaction.
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildPaymentProof(paymentOption: X402PaymentOption, from: `0x${string}`, txHash: `0x${string}`): string;
|
|
21
|
+
/**
|
|
22
|
+
* Full x402 payment flow:
|
|
23
|
+
* 1. Parse 402 challenge
|
|
24
|
+
* 2. Check USDC balance
|
|
25
|
+
* 3. Execute USDC transfer
|
|
26
|
+
* 4. Build payment proof header
|
|
27
|
+
*
|
|
28
|
+
* Returns the encoded X-Payment header value.
|
|
29
|
+
*/
|
|
30
|
+
export declare function handleX402Payment(walletClient: WalletClient<Transport, Chain, Account>, challengeBody: unknown, options?: {
|
|
31
|
+
skipBalanceCheck?: boolean;
|
|
32
|
+
}): Promise<{
|
|
33
|
+
header: string;
|
|
34
|
+
txHash: `0x${string}`;
|
|
35
|
+
amountPaid: bigint;
|
|
36
|
+
}>;
|
|
37
|
+
//# sourceMappingURL=x402.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x402.d.ts","sourceRoot":"","sources":["../src/x402.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,YAAY,EAGlB,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAoB,MAAM,YAAY,CAAC;AA0BrF;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,CAM3D;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EACrD,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EACrD,KAAK,EAAE,KAAK,MAAM,EAAE,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAcxB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,iBAAiB,EAChC,IAAI,EAAE,KAAK,MAAM,EAAE,EACnB,MAAM,EAAE,KAAK,MAAM,EAAE,GACpB,MAAM,CAmBR;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EACrD,aAAa,EAAE,OAAO,EACtB,OAAO,CAAC,EAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBxE"}
|
package/dist/x402.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { createPublicClient, http, } from "viem";
|
|
2
|
+
import { base } from "viem/chains";
|
|
3
|
+
import { PaymentError, InsufficientBalanceError } from "./errors.js";
|
|
4
|
+
// USDC on Base
|
|
5
|
+
const USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
6
|
+
const USDC_ABI = [
|
|
7
|
+
{
|
|
8
|
+
inputs: [
|
|
9
|
+
{ name: "to", type: "address" },
|
|
10
|
+
{ name: "amount", type: "uint256" },
|
|
11
|
+
],
|
|
12
|
+
name: "transfer",
|
|
13
|
+
outputs: [{ name: "", type: "bool" }],
|
|
14
|
+
stateMutability: "nonpayable",
|
|
15
|
+
type: "function",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
inputs: [{ name: "account", type: "address" }],
|
|
19
|
+
name: "balanceOf",
|
|
20
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
21
|
+
stateMutability: "view",
|
|
22
|
+
type: "function",
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* Parse a 402 response body into a structured challenge.
|
|
27
|
+
*/
|
|
28
|
+
export function parseChallenge(body) {
|
|
29
|
+
const challenge = body;
|
|
30
|
+
if (!challenge.accepts || !Array.isArray(challenge.accepts) || challenge.accepts.length === 0) {
|
|
31
|
+
throw new PaymentError("Invalid 402 response: missing payment options");
|
|
32
|
+
}
|
|
33
|
+
return challenge;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if the wallet has enough USDC to cover the payment.
|
|
37
|
+
* Uses a public client for read-only calls.
|
|
38
|
+
*/
|
|
39
|
+
export async function checkBalance(walletClient, amount) {
|
|
40
|
+
const publicClient = createPublicClient({
|
|
41
|
+
chain: walletClient.chain ?? base,
|
|
42
|
+
transport: http(),
|
|
43
|
+
});
|
|
44
|
+
const available = await publicClient.readContract({
|
|
45
|
+
address: USDC_BASE,
|
|
46
|
+
abi: USDC_ABI,
|
|
47
|
+
functionName: "balanceOf",
|
|
48
|
+
args: [walletClient.account.address],
|
|
49
|
+
});
|
|
50
|
+
if (available < amount) {
|
|
51
|
+
throw new InsufficientBalanceError(amount, available);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute USDC transfer on Base to the specified recipient.
|
|
56
|
+
* Returns the transaction hash.
|
|
57
|
+
*/
|
|
58
|
+
export async function executePayment(walletClient, payTo, amount) {
|
|
59
|
+
try {
|
|
60
|
+
const hash = await walletClient.writeContract({
|
|
61
|
+
address: USDC_BASE,
|
|
62
|
+
abi: USDC_ABI,
|
|
63
|
+
functionName: "transfer",
|
|
64
|
+
args: [payTo, amount],
|
|
65
|
+
});
|
|
66
|
+
return hash;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const msg = error instanceof Error ? error.message : "USDC transfer failed";
|
|
70
|
+
throw new PaymentError(`Payment transaction failed: ${msg}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Construct the x402 payment proof from the completed transaction.
|
|
75
|
+
*/
|
|
76
|
+
export function buildPaymentProof(paymentOption, from, txHash) {
|
|
77
|
+
const proof = {
|
|
78
|
+
scheme: paymentOption.scheme,
|
|
79
|
+
network: paymentOption.network,
|
|
80
|
+
payload: {
|
|
81
|
+
authorization: {
|
|
82
|
+
from,
|
|
83
|
+
to: paymentOption.payTo,
|
|
84
|
+
value: paymentOption.maxAmountRequired,
|
|
85
|
+
validAfter: "0",
|
|
86
|
+
validBefore: "9999999999",
|
|
87
|
+
nonce: "0",
|
|
88
|
+
},
|
|
89
|
+
signature: "0x",
|
|
90
|
+
txHash,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
return btoa(JSON.stringify(proof));
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Full x402 payment flow:
|
|
97
|
+
* 1. Parse 402 challenge
|
|
98
|
+
* 2. Check USDC balance
|
|
99
|
+
* 3. Execute USDC transfer
|
|
100
|
+
* 4. Build payment proof header
|
|
101
|
+
*
|
|
102
|
+
* Returns the encoded X-Payment header value.
|
|
103
|
+
*/
|
|
104
|
+
export async function handleX402Payment(walletClient, challengeBody, options) {
|
|
105
|
+
const challenge = parseChallenge(challengeBody);
|
|
106
|
+
const paymentOption = challenge.accepts[0];
|
|
107
|
+
const amount = BigInt(paymentOption.maxAmountRequired);
|
|
108
|
+
// Optionally check balance first to give a better error
|
|
109
|
+
if (!options?.skipBalanceCheck) {
|
|
110
|
+
await checkBalance(walletClient, amount);
|
|
111
|
+
}
|
|
112
|
+
// Execute the USDC transfer
|
|
113
|
+
const txHash = await executePayment(walletClient, paymentOption.payTo, amount);
|
|
114
|
+
// Build the proof header
|
|
115
|
+
const header = buildPaymentProof(paymentOption, walletClient.account.address, txHash);
|
|
116
|
+
return { header, txHash, amountPaid: amount };
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=x402.js.map
|
package/dist/x402.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x402.js","sourceRoot":"","sources":["../src/x402.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opencardsdk/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Client SDK for OpenCard — create virtual cards with USDC payments via x402",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"dev": "tsc --watch",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"opencard",
|
|
26
|
+
"x402",
|
|
27
|
+
"usdc",
|
|
28
|
+
"virtual-card",
|
|
29
|
+
"ai-agent",
|
|
30
|
+
"crypto-payments",
|
|
31
|
+
"base"
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"viem": "^2.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"typescript": "^5.5.0"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"viem": "^2.0.0"
|
|
42
|
+
}
|
|
43
|
+
}
|