@directcryptopay/sdk 0.1.0 → 0.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 (137) hide show
  1. package/README.md +202 -256
  2. package/dist/{add-KF4m4jFK.js → add-DuP4WhxV.js} +1 -1
  3. package/dist/{all-wallets-D6NAjQgX.js → all-wallets-5JBV4CZN.js} +1 -1
  4. package/dist/{app-store-D7TTn-EO.js → app-store-C_iLeXrh.js} +1 -1
  5. package/dist/{apple-DjX2E2hE.js → apple-BXgQe_w8.js} +1 -1
  6. package/dist/{arrow-bottom-C0YrNJYB.js → arrow-bottom-B4Vsa9wq.js} +1 -1
  7. package/dist/{arrow-bottom-circle-Dlxvx_XG.js → arrow-bottom-circle-C1QSwRIp.js} +1 -1
  8. package/dist/{arrow-left-x8_-lUyK.js → arrow-left-pxwCvXD9.js} +1 -1
  9. package/dist/{arrow-right-BTZybj80.js → arrow-right-B8Av1oDN.js} +1 -1
  10. package/dist/{arrow-top-LzH7iLCp.js → arrow-top-DbPtAeXG.js} +1 -1
  11. package/dist/{bank-23jp-IV_.js → bank-De2PNeXL.js} +1 -1
  12. package/dist/{browser-EjoorDid.js → browser-Ds4DBQOP.js} +1 -1
  13. package/dist/{card-DGgWwtwC.js → card-BcxTMuEn.js} +1 -1
  14. package/dist/{ccip-BMANewTU.js → ccip-B4sn4c5Q.js} +2 -2
  15. package/dist/{checkmark-B1qcQhBo.js → checkmark-Cvkmx-sx.js} +1 -1
  16. package/dist/{checkmark-bold-Cyc4IEEJ.js → checkmark-bold-JHvEtJRZ.js} +1 -1
  17. package/dist/{chevron-bottom-ClHs08rB.js → chevron-bottom-lAad_zie.js} +1 -1
  18. package/dist/{chevron-left-O8h_551_.js → chevron-left-Ck9W-Hsf.js} +1 -1
  19. package/dist/{chevron-right-DP3xpyIA.js → chevron-right-DsNh648f.js} +1 -1
  20. package/dist/{chevron-top-CuwkBUs9.js → chevron-top-L90lwzG3.js} +1 -1
  21. package/dist/{chrome-store-zfT_aJ3R.js → chrome-store-DsXX7iqA.js} +1 -1
  22. package/dist/{clock-DHZqivIS.js → clock-DeilmpSa.js} +1 -1
  23. package/dist/{close-Cp9rNAw4.js → close-D4gsZqfR.js} +1 -1
  24. package/dist/{coinPlaceholder-U7-T1KKQ.js → coinPlaceholder-B0Kg8woL.js} +1 -1
  25. package/dist/{compass-Ds5-PRSR.js → compass-BDc1Htlg.js} +1 -1
  26. package/dist/{copy-Jg4HdIMf.js → copy-Ddroiv6f.js} +1 -1
  27. package/dist/core/api.d.ts +10 -1
  28. package/dist/core/wallet.d.ts +23 -2
  29. package/dist/{cursor-DmMevduB.js → cursor-DIunlIJp.js} +1 -1
  30. package/dist/{cursor-transparent-Dn9-1SV8.js → cursor-transparent-CXfl0bNj.js} +1 -1
  31. package/dist/dcp-sdk.umd.js +478 -478
  32. package/dist/dcp.d.ts +11 -1
  33. package/dist/{desktop-C4udXXlZ.js → desktop-CDp5ghZ6.js} +1 -1
  34. package/dist/{disconnect-wd1BYLxt.js → disconnect-DUI9ddIg.js} +1 -1
  35. package/dist/{discord-DthxuCAP.js → discord-D_apxuxu.js} +1 -1
  36. package/dist/{email-B3jSnUFE.js → email-DCvzZXYk.js} +8 -8
  37. package/dist/{embedded-wallet-CJHmoBI2.js → embedded-wallet-CHAaqj_k.js} +11 -11
  38. package/dist/{etherscan-Cjp4xfMW.js → etherscan-BYrw6lJt.js} +1 -1
  39. package/dist/{exclamation-triangle-CRNR5WOy.js → exclamation-triangle-C31EobMQ.js} +1 -1
  40. package/dist/{extension-Cydk0mZt.js → extension-CchWONzJ.js} +1 -1
  41. package/dist/{external-link-CuPTAoq9.js → external-link-CebHOeWd.js} +1 -1
  42. package/dist/{facebook-CghqXmdf.js → facebook-CD3lppZ5.js} +1 -1
  43. package/dist/{farcaster-BREqMX4y.js → farcaster-lZUkqUmB.js} +1 -1
  44. package/dist/{filters-Dn_Ys7ew.js → filters-D3KWfhyO.js} +1 -1
  45. package/dist/{github-C-A7JmIY.js → github-Cvv_sOWq.js} +1 -1
  46. package/dist/{google-CCdM_naE.js → google-DoFICkCj.js} +1 -1
  47. package/dist/{hashTypedData-D2Qmzscs.js → hashTypedData-BHHGGXNO.js} +1 -1
  48. package/dist/{help-circle-DIH4vyj3.js → help-circle-CiSClrc6.js} +1 -1
  49. package/dist/{id-DkJ0gBuy.js → id-mmauIL1Q.js} +1 -1
  50. package/dist/{if-defined-BciplFKz.js → if-defined-B9A-SuEH.js} +78 -78
  51. package/dist/{image-qMjyiXM0.js → image-CPddwR98.js} +1 -1
  52. package/dist/{index-Da8oZh8H.js → index--wY2C4T3.js} +10 -10
  53. package/dist/{index-B2-vKLd8.js → index-0UuJZssH.js} +5 -5
  54. package/dist/{index-CTYngdl0.js → index-1E6II94R.js} +1 -1
  55. package/dist/{index-BdjxQs66.js → index-5QBTZwil.js} +5 -5
  56. package/dist/{index-Ij6XA6_4.js → index-8MHsCmjw.js} +2 -2
  57. package/dist/{index-DmOMXRG1.js → index-B-EQbBE1.js} +2 -2
  58. package/dist/{index-BpXOsxzU.js → index-B7MBnU8U.js} +2 -2
  59. package/dist/{index-AvC0IGDl.js → index-B8WZTprM.js} +28 -28
  60. package/dist/{index-eW8y-mXH.js → index-BGf41hyR.js} +3 -3
  61. package/dist/{index-D-IzHD_8.js → index-BR3OZ5tY.js} +2 -2
  62. package/dist/{index-B2iDt0TJ.js → index-BZlEkYh1.js} +2 -2
  63. package/dist/{index-B5zkXsLJ.js → index-BbwmpqkC.js} +4 -4
  64. package/dist/{index-fxzIDZsb.js → index-BflWdkJX.js} +2 -2
  65. package/dist/{index-B7K86vWu.js → index-Bm_umjg-.js} +3 -3
  66. package/dist/{index-BBkcvSiY.js → index-BwZg5eKW.js} +3 -3
  67. package/dist/{index-CwB_qRfM.js → index-BziWxDLL.js} +3 -3
  68. package/dist/{index-DRNiFv9I.js → index-C21v4yzv.js} +5 -5
  69. package/dist/{index-C27dwOyE.js → index-CKt3c7vP.js} +3 -3
  70. package/dist/{index-CqVegmN4.js → index-CcxAAnYa.js} +6 -6
  71. package/dist/{index-lbhz9evJ.js → index-ChHzzHKf.js} +2 -2
  72. package/dist/{index-CuiyMA8F.js → index-CqJkW7ok.js} +3 -3
  73. package/dist/{index-CUdQyyFn.js → index-DPQg2zed.js} +2 -2
  74. package/dist/{index--3Zp0jAb.js → index-DQvOQPAe.js} +2 -2
  75. package/dist/{index-C4BX3QW8.js → index-DVrXX4wp.js} +3 -3
  76. package/dist/{index-Bijd4_Ns.js → index-Da-qfVsI.js} +3 -3
  77. package/dist/{index-CxOF7GqE.js → index-DiGq7Twa.js} +3 -3
  78. package/dist/{index-CppCc1n8.js → index-Dn2u8IZ4.js} +2 -2
  79. package/dist/{index-CMPIqsB1.js → index-Dz5Y9DG0.js} +3 -3
  80. package/dist/{index-DoSYqTQg.js → index-K-vs5VBY.js} +3 -3
  81. package/dist/{index-DtCsAVBg.js → index-K3CyIFHA.js} +2 -2
  82. package/dist/{index-DpHXq5_E.js → index-Qo-WDoO6.js} +2 -2
  83. package/dist/{index-CX60z_g2.js → index-UdoiPkDs.js} +4 -4
  84. package/dist/{index-DiHImG4L.js → index-ZbZVGyW9.js} +9678 -9430
  85. package/dist/{index-1adX-Fit.js → index-lUi7mcYP.js} +2 -2
  86. package/dist/{index-SzyBYfzA.js → index-ypbesXfX.js} +5 -5
  87. package/dist/index.d.ts +1 -1
  88. package/dist/index.js +1 -1
  89. package/dist/{info-DMIGgjkL.js → info-DUUpq3A8.js} +1 -1
  90. package/dist/{info-circle-CJuIKZSx.js → info-circle-71ComNpv.js} +1 -1
  91. package/dist/{lightbulb-qFT6WEWV.js → lightbulb-Dn8yehyg.js} +1 -1
  92. package/dist/{localBatchGatewayRequest-CsMVMFBc.js → localBatchGatewayRequest-22JZkkT_.js} +1 -1
  93. package/dist/{mail-DoYgQvOt.js → mail-CsDptbSx.js} +1 -1
  94. package/dist/{mobile-URtsh7o-.js → mobile-CPJuZx44.js} +1 -1
  95. package/dist/{more-DoQd10TF.js → more-BOYxX2nP.js} +1 -1
  96. package/dist/{network-placeholder-BBA2Ue6C.js → network-placeholder-VYjYxNG4.js} +1 -1
  97. package/dist/{nftPlaceholder-C9RXWz9k.js → nftPlaceholder-CG0quU6c.js} +1 -1
  98. package/dist/{off-YcuDQczT.js → off-Bx28ns6u.js} +1 -1
  99. package/dist/{onramp-BfqDIx4o.js → onramp-BBC60CcF.js} +13 -13
  100. package/dist/{parseSignature-280HB24T.js → parseSignature-8IN1QgOo.js} +4 -4
  101. package/dist/{play-store-sFaloG_r.js → play-store-CNp25d_w.js} +1 -1
  102. package/dist/{plus-l0wekSht.js → plus-CQaRn4R3.js} +1 -1
  103. package/dist/{qr-code-CihrUU4G.js → qr-code-QBtVvbvs.js} +1 -1
  104. package/dist/{receive-dfY1Cu-g.js → receive-DXWRBTEQ.js} +5 -5
  105. package/dist/{recycle-horizontal-nXu6YaPw.js → recycle-horizontal-CpnSrRdg.js} +1 -1
  106. package/dist/{ref-huAzXCX0.js → ref-C6IIbwxq.js} +2 -2
  107. package/dist/{refresh-D2ZbVeNC.js → refresh-DY_Dx78p.js} +1 -1
  108. package/dist/{reown-logo-BMaTMJmc.js → reown-logo-DVm_TEc7.js} +1 -1
  109. package/dist/{search-YVM9q3J-.js → search-ClJskXVW.js} +1 -1
  110. package/dist/{secp256k1-DPQgTBwQ.js → secp256k1-CQ19DtRL.js} +1 -1
  111. package/dist/{secp256k1-BrysY3Sv.js → secp256k1-X5XIlSn6.js} +1 -1
  112. package/dist/{send-GyetMVu1.js → send-P3r6OIjm.js} +11 -11
  113. package/dist/{send-BwQZPKxI.js → send-TqSroVbV.js} +1 -1
  114. package/dist/{socials-B0W91J9k.js → socials-4JUgml5Z.js} +10 -10
  115. package/dist/{swapHorizontal-Dy_oQEkp.js → swapHorizontal-8KilA_OC.js} +1 -1
  116. package/dist/{swapHorizontalBold-C4JpaMpc.js → swapHorizontalBold-Bl9gJ64j.js} +1 -1
  117. package/dist/{swapHorizontalMedium-D5NuVZFh.js → swapHorizontalMedium-DDyLmVwC.js} +1 -1
  118. package/dist/{swapHorizontalRoundedBold-Bq4P2MCj.js → swapHorizontalRoundedBold-6ZYHYdUX.js} +1 -1
  119. package/dist/{swapVertical-CVQ8Mg03.js → swapVertical-BRgBuh_B.js} +1 -1
  120. package/dist/{swaps-CA04SSdK.js → swaps-CxJvguLy.js} +9 -9
  121. package/dist/{telegram-BP4SgW_L.js → telegram-OC2IKNlW.js} +1 -1
  122. package/dist/{three-dots-BJYGJ-dQ.js → three-dots-CYzCkBQ2.js} +1 -1
  123. package/dist/{transactions-Bq-98Tsg.js → transactions-CwFjYgL1.js} +3 -3
  124. package/dist/{twitch-DTATWo9M.js → twitch-CDW38k5a.js} +1 -1
  125. package/dist/{twitterIcon-D5UWPInb.js → twitterIcon-D6-ODkwM.js} +1 -1
  126. package/dist/types.d.ts +60 -0
  127. package/dist/ui/Modal.d.ts +3 -3
  128. package/dist/ui/index.d.ts +2 -2
  129. package/dist/{verify-Byvj8Wi1.js → verify-VZiPZ9WI.js} +1 -1
  130. package/dist/{verify-filled-B40taNm0.js → verify-filled-BpF4F1jG.js} +1 -1
  131. package/dist/{w3m-modal-HV6SE74G.js → w3m-modal-DZu8ry9r.js} +9 -9
  132. package/dist/{wallet-Cp-6Kk88.js → wallet-CvQjQVxz.js} +1 -1
  133. package/dist/{wallet-placeholder-C3juwA9o.js → wallet-placeholder-B1BHI_2j.js} +1 -1
  134. package/dist/{walletconnect-CRkIiLCx.js → walletconnect-Cnjk-qmM.js} +1 -1
  135. package/dist/{warning-circle-DtvCLwG4.js → warning-circle-DvWTcM8j.js} +1 -1
  136. package/dist/{x-Cqyx5eCt.js → x-BCQWBooq.js} +1 -1
  137. package/package.json +1 -1
package/README.md CHANGED
@@ -1,14 +1,15 @@
1
1
  # @directcryptopay/sdk
2
2
 
3
- Official TypeScript/JavaScript SDK for DirectCryptoPay. Create payment intents, verify webhooks, and manage crypto payments from Node.js, Edge Functions, or the browser.
3
+ Official SDK for DirectCryptoPay accept crypto payments directly to your wallet. Non-custodial, multi-chain, developer-first.
4
4
 
5
5
  ## Features
6
6
 
7
- **TypeScript-first** - Full type safety with exported types
8
- **Web Crypto API** - Works in Node.js, Edge (Vercel, Cloudflare), and browsers
9
- **Webhook verification** - HMAC-SHA256 signature validation
10
- **Zero dependencies** - Lightweight, uses only platform APIs
11
- **Idempotency support** - Prevent duplicate requests
7
+ - **Non-custodial** Funds go directly from customer wallet to yours
8
+ - **Multi-chain** Ethereum, Polygon, BNB Chain, Base, Arbitrum, Optimism (mainnet + testnet)
9
+ - **Shadow DOM isolation** Payment modal won't interfere with your app's styles or state
10
+ - **WalletConnect support** MetaMask, Rabby, WalletConnect, and 300+ wallets via Reown AppKit
11
+ - **Two payment modes** — Tool-based (pre-configured) or Integration-based (dynamic amounts)
12
+ - **TypeScript-first** — Full type safety with exported types
12
13
 
13
14
  ## Installation
14
15
 
@@ -22,335 +23,280 @@ yarn add @directcryptopay/sdk
22
23
 
23
24
  ## Quick Start
24
25
 
25
- ### Server-side: Create Payment Intent
26
+ ### 1. Initialize the SDK
26
27
 
27
- ```typescript
28
- import { DirectCryptoPay } from '@directcryptopay/sdk';
29
-
30
- const dcp = new DirectCryptoPay({
31
- baseURL: 'https://test-api.directcryptopay.com',
32
- apiKey: process.env.DCP_API_KEY!,
33
- });
34
-
35
- const intent = await dcp.createPaymentIntent({
36
- amount: 49.99,
37
- currency: 'USD',
38
- metadata: {
39
- order_id: 'ORD-123',
40
- customer_email: 'customer@example.com'
41
- },
42
- idempotencyKey: crypto.randomUUID(), // Recommended
43
- });
44
-
45
- console.log(intent.id); // pi_abc123...
46
- console.log(intent.recipient); // 0x1234...
47
- console.log(intent.amount_wei); // "50000000000000000"
48
- ```
49
-
50
- ### Server-side: Verify Webhook
28
+ Call `DCP.init()` once when your app loads. You need a [Reown project ID](https://cloud.reown.com) (free) for WalletConnect support.
51
29
 
52
30
  ```typescript
53
- import { verifyWebhookSignature } from '@directcryptopay/sdk';
54
-
55
- export async function POST(req: Request) {
56
- const rawBody = await req.text();
57
- const signature = req.headers.get('x-dcp-signature') ?? '';
58
-
59
- const isValid = await verifyWebhookSignature({
60
- rawBody,
61
- signatureHeader: signature,
62
- secret: process.env.DCP_WEBHOOK_SECRET!,
63
- });
64
-
65
- if (!isValid) {
66
- return new Response('Invalid signature', { status: 400 });
67
- }
68
-
69
- const event = JSON.parse(rawBody);
70
-
71
- if (event.event === 'payment.succeeded') {
72
- // Handle payment success
73
- console.log('Payment confirmed:', event.data.id);
74
- }
75
-
76
- return new Response('OK', { status: 200 });
77
- }
78
- ```
79
-
80
- ## API Reference
81
-
82
- ### `DirectCryptoPay`
83
-
84
- Main SDK class for interacting with DirectCryptoPay API.
31
+ import { DCP } from '@directcryptopay/sdk';
85
32
 
86
- #### Constructor
87
-
88
- ```typescript
89
- const dcp = new DirectCryptoPay({
90
- baseURL: string; // e.g., 'https://api.directcryptopay.com'
91
- apiKey: string; // Your server-side API key
92
- fetch?: typeof fetch; // Optional: custom fetch (for testing)
33
+ DCP.init({
34
+ projectId: 'your-reown-project-id', // Free at cloud.reown.com
93
35
  });
94
36
  ```
95
37
 
96
- #### Methods
38
+ ### 2. Accept a payment
97
39
 
98
- ##### `createPaymentIntent(input)`
99
-
100
- Create a new payment intent.
40
+ **Option A: Payment Tool** (pre-configured amount, token, and chain)
101
41
 
102
42
  ```typescript
103
- const intent = await dcp.createPaymentIntent({
104
- amount: 49.99,
105
- currency: 'USD',
106
- metadata?: { order_id: 'ORD-123' },
107
- expiry_seconds?: 900, // Default: 900 (15 min)
108
- idempotencyKey?: string, // Recommended
43
+ DCP.pay({
44
+ toolId: 'your-tool-id', // From Dashboard > Payment Tools > Get Code
45
+ callbacks: {
46
+ onSuccess: (data) => {
47
+ console.log('Payment confirmed:', data);
48
+ },
49
+ onError: (error) => {
50
+ console.error('Payment failed:', error);
51
+ },
52
+ },
109
53
  });
110
54
  ```
111
55
 
112
- **Returns:** `Promise<Intent>`
113
-
114
- ##### `declareTx(input)`
115
-
116
- Declare a blockchain transaction for a payment intent.
56
+ **Option B: Integration** (dynamic amount, token selector)
117
57
 
118
58
  ```typescript
119
- await dcp.declareTx({
120
- intentId: 'pi_abc123',
121
- txHash: '0x1234...',
122
- idempotencyKey?: string,
59
+ DCP.Payment({
60
+ integrationId: 'your-integration-id',
61
+ amount_usd: '49.99',
62
+ callbacks: {
63
+ onSuccess: (data) => {
64
+ console.log('Paid:', data.txHash);
65
+ },
66
+ },
123
67
  });
124
68
  ```
125
69
 
126
- **Returns:** `Promise<{ accepted: true }>`
127
-
128
- ##### `getIntentStatus(intentId)`
129
-
130
- Get current status of a payment intent.
131
-
132
- ```typescript
133
- const intent = await dcp.getIntentStatus('pi_abc123');
134
- console.log(intent.status); // 'created' | 'pending' | 'paid' | 'failed' | 'expired'
135
- ```
136
-
137
- **Returns:** `Promise<Intent>`
70
+ ## API Reference
138
71
 
139
- ##### `waitForConfirmation(intentId, options?)`
72
+ ### `DCP.init(config)`
140
73
 
141
- Poll for payment confirmation with automatic retry.
74
+ Initialize the SDK. Must be called once before `pay()` or `Payment()`.
142
75
 
143
76
  ```typescript
144
- const confirmedIntent = await dcp.waitForConfirmation('pi_abc123', {
145
- intervalMs: 2000, // Poll every 2 seconds
146
- maxAttempts: 60, // Max 60 attempts (2 min total)
147
- onTick: (attempt, status) => {
148
- console.log(`Attempt ${attempt}: ${status}`);
149
- },
77
+ DCP.init({
78
+ projectId: string; // Required Reown/WalletConnect project ID
79
+ apiUrl?: string; // Default: 'https://api.directcryptopay.com'
80
+ defaultChainId?: number; // Default chain for wallet connection
81
+ gasWarningThreshold?: number; // Gas warning % threshold (default: 15)
82
+ env?: 'test' | 'prod'; // Environment hint
150
83
  });
151
-
152
- console.log('Payment confirmed:', confirmedIntent.tx_hash);
153
84
  ```
154
85
 
155
- **Returns:** `Promise<Intent>` (with `status: 'paid'`)
156
- **Throws:** If payment fails, expires, or times out
157
-
158
- ##### `listPaymentIntents(options?)`
86
+ ### `DCP.pay(options)`
159
87
 
160
- List payment intents with pagination.
88
+ Open the payment modal for a pre-configured Payment Tool. The tool defines the amount, accepted tokens, and target chain.
161
89
 
162
90
  ```typescript
163
- const { data, hasMore, nextCursor } = await dcp.listPaymentIntents({
164
- limit: 20,
165
- cursor: 'cursor_abc',
166
- status: 'paid',
91
+ DCP.pay({
92
+ toolId: string; // Required — Payment Tool ID
93
+ amountUsd?: number; // Override USD amount (for donations)
94
+ token?: string; // Pre-select token symbol
95
+ chainId?: number; // Pre-select chain
96
+ metadata?: Record<string, string>; // Custom metadata
97
+ callbacks?: PaymentCallbacks; // Event handlers
167
98
  });
168
99
  ```
169
100
 
170
- **Returns:** `Promise<{ data: Intent[], hasMore: boolean, nextCursor?: string }>`
101
+ ### `DCP.Payment(options)`
171
102
 
172
- ### `verifyWebhookSignature(options)`
173
-
174
- Verify HMAC-SHA256 webhook signature (timing-safe).
103
+ Open the payment modal for an Integration-based payment. Use this for dynamic amounts (carts, subscriptions, per-user pricing).
175
104
 
176
105
  ```typescript
177
- const isValid = await verifyWebhookSignature({
178
- rawBody: string, // Request body as string (exact as received)
179
- signatureHeader: string, // 'X-DCP-Signature' header value
180
- secret: string, // Your webhook secret
181
- toleranceSec?: number, // Default: 300 (5 minutes)
106
+ DCP.Payment({
107
+ integrationId: string; // Required Integration public ID
108
+ amount_usd?: string; // Amount in USD (e.g., '49.99')
109
+ amount?: string | number; // OR amount in token units (not both)
110
+ currency?: string; // Pre-select token (skips selector if set)
111
+ chainId?: number; // Pre-select chain
112
+ metadata?: Record<string, any>; // Custom metadata
113
+ callbacks?: PaymentCallbacks; // Event handlers
182
114
  });
183
115
  ```
184
116
 
185
- **Returns:** `Promise<boolean>`
117
+ > **Note:** Provide either `amount_usd` or `amount`, not both.
186
118
 
187
- ## Types
119
+ ### Callbacks
188
120
 
189
- All types are exported:
121
+ All callbacks are optional.
190
122
 
191
123
  ```typescript
192
- import type {
193
- Intent,
194
- PaymentStatus,
195
- CreateIntentInput,
196
- DeclareTxInput,
197
- SdkConfig,
198
- ChainId,
199
- } from '@directcryptopay/sdk';
200
- ```
201
-
202
- ### `Intent`
203
-
204
- ```typescript
205
- interface Intent {
206
- id: string;
207
- chain_id: ChainId;
208
- recipient: `0x${string}`;
209
- amount_wei: string;
210
- currency: string;
211
- amount: number;
212
- expires_at: string;
213
- status: PaymentStatus;
214
- signature: string;
215
- asset_type: 'native' | 'erc20';
216
- token_address?: `0x${string}`;
217
- tx_hash?: `0x${string}`;
218
- confirmed_at?: string;
124
+ interface PaymentCallbacks {
125
+ onOpen?: () => void; // Modal opened
126
+ onClose?: () => void; // Modal closed
127
+ onStatus?: (status: PaymentStatus) => void; // Status updates
128
+ onTxSubmitted?: (txHash: string) => void; // Transaction sent to chain
129
+ onSuccess?: (data: any) => void; // Payment confirmed
130
+ onCancel?: () => void; // User cancelled
131
+ onError?: (error: Error) => void; // Error occurred
219
132
  }
220
133
  ```
221
134
 
222
- ### `PaymentStatus`
135
+ ### Payment Status
136
+
137
+ Real-time status updates via `onStatus`:
223
138
 
224
139
  ```typescript
225
- type PaymentStatus = 'created' | 'pending' | 'paid' | 'failed' | 'expired' | 'late_confirmed';
140
+ type PaymentStatus =
141
+ | { type: 'fetching_tool_data' }
142
+ | { type: 'fetching_token_balances' }
143
+ | { type: 'awaiting_token_selection' }
144
+ | { type: 'creating_payment_intent' }
145
+ | { type: 'estimating_gas' }
146
+ | { type: 'gas_estimated'; estimate: GasEstimate }
147
+ | { type: 'awaiting_wallet_connection' }
148
+ | { type: 'wallet_connected'; address: string }
149
+ | { type: 'awaiting_signature' }
150
+ | { type: 'transaction_submitted'; txHash: string }
151
+ | { type: 'confirming'; txHash: string; confirmations: number }
152
+ | { type: 'verifying'; txHash: string; paymentId: string }
153
+ | { type: 'confirmed'; txHash: string; paymentId?: string }
154
+ | { type: 'failed'; error: Error }
155
+ | { type: 'rejected' }
156
+ | { type: 'cancelled' };
226
157
  ```
227
158
 
228
- ## Usage Examples
159
+ ## Framework Examples
229
160
 
230
- ### Next.js API Route (App Router)
161
+ ### Next.js (App Router)
231
162
 
232
- ```typescript
233
- // app/api/dcp/create-intent/route.ts
234
- import { DirectCryptoPay } from '@directcryptopay/sdk';
163
+ **1. Create a provider:**
235
164
 
236
- const dcp = new DirectCryptoPay({
237
- baseURL: process.env.DCP_API_BASE!,
238
- apiKey: process.env.DCP_API_KEY!,
239
- });
165
+ ```tsx
166
+ // components/DCPProvider.tsx
167
+ 'use client';
240
168
 
241
- export async function POST(req: Request) {
242
- const { amount, currency } = await req.json();
169
+ import { useEffect } from 'react';
170
+ import { DCP } from '@directcryptopay/sdk';
243
171
 
244
- const intent = await dcp.createPaymentIntent({
245
- amount,
246
- currency,
247
- idempotencyKey: crypto.randomUUID(),
248
- });
172
+ export function DCPProvider({ children }: { children: React.ReactNode }) {
173
+ useEffect(() => {
174
+ DCP.init({
175
+ projectId: 'your-reown-project-id'
176
+ });
177
+ }, []);
249
178
 
250
- return Response.json(intent);
179
+ return <>{children}</>;
251
180
  }
252
181
  ```
253
182
 
254
- ### Next.js Webhook Handler
255
-
256
- ```typescript
257
- // app/api/dcp/webhook/route.ts
258
- import { verifyWebhookSignature } from '@directcryptopay/sdk';
183
+ **2. Wrap your layout:**
259
184
 
260
- export async function POST(req: Request) {
261
- const rawBody = await req.text();
262
- const signature = req.headers.get('x-dcp-signature') ?? '';
185
+ ```tsx
186
+ // app/layout.tsx
187
+ import { DCPProvider } from '@/components/DCPProvider';
263
188
 
264
- const isValid = await verifyWebhookSignature({
265
- rawBody,
266
- signatureHeader: signature,
267
- secret: process.env.DCP_WEBHOOK_SECRET!,
268
- });
269
-
270
- if (!isValid) {
271
- return new Response('Invalid signature', { status: 400 });
272
- }
273
-
274
- const event = JSON.parse(rawBody);
275
-
276
- switch (event.event) {
277
- case 'payment.succeeded':
278
- // Handle success
279
- break;
280
- case 'payment.failed':
281
- // Handle failure
282
- break;
283
- }
189
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
190
+ return (
191
+ <html lang="en">
192
+ <body>
193
+ <DCPProvider>{children}</DCPProvider>
194
+ </body>
195
+ </html>
196
+ );
197
+ }
198
+ ```
284
199
 
285
- return new Response('OK');
200
+ **3. Create a pay button:**
201
+
202
+ ```tsx
203
+ // components/PayButton.tsx
204
+ 'use client';
205
+
206
+ import { useState } from 'react';
207
+ import { DCP } from '@directcryptopay/sdk';
208
+
209
+ export function PayButton({ toolId, label = 'Pay with Crypto' }: {
210
+ toolId: string;
211
+ label?: string;
212
+ }) {
213
+ const [status, setStatus] = useState<string | null>(null);
214
+
215
+ const handlePay = () => {
216
+ setStatus('pending');
217
+ DCP.pay({
218
+ toolId,
219
+ callbacks: {
220
+ onSuccess: (data) => {
221
+ setStatus('confirmed');
222
+ console.log('Payment confirmed:', data);
223
+ },
224
+ onError: (error) => {
225
+ setStatus('failed');
226
+ console.error('Payment failed:', error);
227
+ },
228
+ onClose: () => setStatus(null),
229
+ }
230
+ });
231
+ };
232
+
233
+ return (
234
+ <button onClick={handlePay} disabled={status === 'pending'}>
235
+ {status === 'confirmed' ? 'Payment Confirmed!' :
236
+ status === 'pending' ? 'Processing...' : label}
237
+ </button>
238
+ );
286
239
  }
287
240
  ```
288
241
 
289
- ### Cloudflare Workers / Edge
242
+ ### Vanilla JavaScript
290
243
 
291
- ```typescript
292
- export default {
293
- async fetch(req: Request, env: Env) {
294
- const dcp = new DirectCryptoPay({
295
- baseURL: 'https://api.directcryptopay.com',
296
- apiKey: env.DCP_API_KEY,
297
- });
244
+ ```html
245
+ <script type="module">
246
+ import { DCP } from 'https://unpkg.com/@directcryptopay/sdk/dist/index.js';
298
247
 
299
- const intent = await dcp.createPaymentIntent({
300
- amount: 99.99,
301
- currency: 'USD',
302
- });
248
+ DCP.init({ projectId: 'your-reown-project-id' });
303
249
 
304
- return new Response(JSON.stringify(intent), {
305
- headers: { 'Content-Type': 'application/json' },
250
+ document.getElementById('pay-btn').addEventListener('click', () => {
251
+ DCP.pay({
252
+ toolId: 'your-tool-id',
253
+ callbacks: {
254
+ onSuccess: (data) => alert('Payment confirmed!'),
255
+ onError: (error) => alert('Payment failed: ' + error.message),
256
+ }
306
257
  });
307
- },
308
- };
258
+ });
259
+ </script>
309
260
  ```
310
261
 
311
- ## Security Best Practices
262
+ ## Supported Networks
312
263
 
313
- ### DO:
264
+ | Network | Chain ID | Type |
265
+ |---------|----------|------|
266
+ | Ethereum | 1 | Mainnet |
267
+ | Polygon | 137 | Mainnet |
268
+ | BNB Chain | 56 | Mainnet |
269
+ | Base | 8453 | Mainnet |
270
+ | Arbitrum One | 42161 | Mainnet |
271
+ | Optimism | 10 | Mainnet |
272
+ | Sepolia | 11155111 | Testnet |
273
+ | Polygon Amoy | 80002 | Testnet |
274
+ | BNB Testnet | 97 | Testnet |
275
+ | Base Sepolia | 84532 | Testnet |
276
+ | Arbitrum Sepolia | 421614 | Testnet |
277
+ | Optimism Sepolia | 11155420 | Testnet |
314
278
 
315
- 1. **Always verify webhook signatures** using `verifyWebhookSignature`
316
- 2. **Use environment variables** for API keys and secrets
317
- 3. **Use HTTPS in production**
318
- 4. **Use idempotency keys** to prevent duplicate payments
319
- 5. **Validate payment amounts** server-side before fulfillment
279
+ ## Security
320
280
 
321
- ### DON'T:
281
+ The frontend callbacks (`onSuccess`, `onError`) are for **UX purposes only** — updating your UI when a payment completes. For production apps, always verify payments server-side using [webhooks](https://docs.directcryptopay.com).
322
282
 
323
- 1. **Never expose API keys** to the client (browser)
324
- 2. **Never trust client-side payment amounts**
325
- 3. **Never skip signature verification** on webhooks
326
- 4. **Never hardcode secrets** in source code
283
+ DirectCryptoPay is non-custodial: transactions go directly from the customer's wallet to your wallet address. No funds are held by DirectCryptoPay at any point.
327
284
 
328
285
  ## Testing
329
286
 
330
- The SDK uses Web Crypto API which works in:
331
-
332
- - Node.js 16+ (with `globalThis.crypto`)
333
- - Deno
334
- - Cloudflare Workers
335
- - Vercel Edge Functions
336
- - Modern browsers
337
-
338
- ### Test Networks
339
-
340
- - **Sepolia** (Ethereum) - chainId: 11155111
341
- - **Polygon Amoy** - chainId: 80002
342
- - **BSC Testnet** - chainId: 97
343
-
344
- ### Get Test Tokens
287
+ Both testnet and mainnet are available on every account from day one. Test with:
345
288
 
346
- - Sepolia ETH: https://sepoliafaucet.com
347
- - Sepolia USDC: https://faucet.circle.com
289
+ - **Sepolia ETH:** [sepoliafaucet.com](https://sepoliafaucet.com)
290
+ - **Sepolia USDC:** [faucet.circle.com](https://faucet.circle.com)
348
291
 
349
- ## Support
292
+ ## Links
350
293
 
351
- - **Documentation:** https://docs.directcryptopay.com
352
- - **API Reference:** https://api.directcryptopay.com/docs
353
- - **Dashboard:** https://app.directcryptopay.com
294
+ - **Website:** [directcryptopay.com](https://directcryptopay.com)
295
+ - **Dashboard:** [directcryptopay.com/dashboard](https://directcryptopay.com/dashboard)
296
+ - **Documentation:** [docs.directcryptopay.com](https://docs.directcryptopay.com)
297
+ - **API Docs:** [api.directcryptopay.com/api/docs](https://api.directcryptopay.com/api/docs)
298
+ - **Discord:** [discord.com/invite/PPdJNkXh](https://discord.com/invite/PPdJNkXh)
299
+ - **GitHub:** [github.com/directcryptopay](https://github.com/directcryptopay)
354
300
 
355
301
  ## License
356
302
 
@@ -1,4 +1,4 @@
1
- import { cy as l } from "./index-DiHImG4L.js";
1
+ import { cy as l } from "./index-ZbZVGyW9.js";
2
2
  const o = l`<svg
3
3
  width="14"
4
4
  height="14"
@@ -1,4 +1,4 @@
1
- import { cy as a } from "./index-DiHImG4L.js";
1
+ import { cy as a } from "./index-ZbZVGyW9.js";
2
2
  const o = a`<svg fill="none" viewBox="0 0 24 24">
3
3
  <path
4
4
  style="fill: var(--wui-color-accent-100);"
@@ -1,4 +1,4 @@
1
- import { cy as a } from "./index-DiHImG4L.js";
1
+ import { cy as a } from "./index-ZbZVGyW9.js";
2
2
  const e = a`
3
3
  <svg width="36" height="36">
4
4
  <path
@@ -1,4 +1,4 @@
1
- import { cy as l } from "./index-DiHImG4L.js";
1
+ import { cy as l } from "./index-ZbZVGyW9.js";
2
2
  const f = l`<svg fill="none" viewBox="0 0 40 40">
3
3
  <g clip-path="url(#a)">
4
4
  <g clip-path="url(#b)">
@@ -1,4 +1,4 @@
1
- import { cy as o } from "./index-DiHImG4L.js";
1
+ import { cy as o } from "./index-ZbZVGyW9.js";
2
2
  const e = o`<svg fill="none" viewBox="0 0 14 15">
3
3
  <path
4
4
  fill="currentColor"
@@ -1,4 +1,4 @@
1
- import { cy as C } from "./index-DiHImG4L.js";
1
+ import { cy as C } from "./index-ZbZVGyW9.js";
2
2
  const e = C`<svg
3
3
  fill="none"
4
4
  viewBox="0 0 21 20"
@@ -1,4 +1,4 @@
1
- import { cy as e } from "./index-DiHImG4L.js";
1
+ import { cy as e } from "./index-ZbZVGyW9.js";
2
2
  const o = e`<svg fill="none" viewBox="0 0 14 15">
3
3
  <path
4
4
  fill="currentColor"
@@ -1,4 +1,4 @@
1
- import { cy as l } from "./index-DiHImG4L.js";
1
+ import { cy as l } from "./index-ZbZVGyW9.js";
2
2
  const e = l`<svg fill="none" viewBox="0 0 14 15">
3
3
  <path
4
4
  fill="currentColor"
@@ -1,4 +1,4 @@
1
- import { cy as o } from "./index-DiHImG4L.js";
1
+ import { cy as o } from "./index-ZbZVGyW9.js";
2
2
  const e = o`<svg fill="none" viewBox="0 0 14 15">
3
3
  <path
4
4
  fill="currentColor"
@@ -1,4 +1,4 @@
1
- import { cy as e } from "./index-DiHImG4L.js";
1
+ import { cy as e } from "./index-ZbZVGyW9.js";
2
2
  const o = e`<svg
3
3
  xmlns="http://www.w3.org/2000/svg"
4
4
  width="12"
@@ -1,4 +1,4 @@
1
- import { cy as l } from "./index-DiHImG4L.js";
1
+ import { cy as l } from "./index-ZbZVGyW9.js";
2
2
  const a = l`<svg fill="none" viewBox="0 0 20 20">
3
3
  <path
4
4
  fill="currentColor"
@@ -1,4 +1,4 @@
1
- import { cy as C } from "./index-DiHImG4L.js";
1
+ import { cy as C } from "./index-ZbZVGyW9.js";
2
2
  const l = C`<svg
3
3
  xmlns="http://www.w3.org/2000/svg"
4
4
  width="12"
@@ -1,5 +1,5 @@
1
- import { a1 as p, cL as y, cq as w, bf as g, br as k, cM as L, bB as E, bi as O, aA as m, bE as x } from "./index-DiHImG4L.js";
2
- import { l as R, b as M } from "./localBatchGatewayRequest-CsMVMFBc.js";
1
+ import { a1 as p, cL as y, cq as w, bf as g, br as k, cM as L, bB as E, bi as O, aA as m, bE as x } from "./index-ZbZVGyW9.js";
2
+ import { l as R, b as M } from "./localBatchGatewayRequest-22JZkkT_.js";
3
3
  class q extends p {
4
4
  constructor({ callbackSelector: r, cause: a, data: n, extraData: i, sender: f, urls: t }) {
5
5
  var o;
@@ -1,4 +1,4 @@
1
- import { cy as e } from "./index-DiHImG4L.js";
1
+ import { cy as e } from "./index-ZbZVGyW9.js";
2
2
  const o = e`<svg
3
3
  width="28"
4
4
  height="28"
@@ -1,4 +1,4 @@
1
- import { cy as e } from "./index-DiHImG4L.js";
1
+ import { cy as e } from "./index-ZbZVGyW9.js";
2
2
  const o = e`<svg fill="none" viewBox="0 0 14 14">
3
3
  <path
4
4
  fill="currentColor"