@caspay/sdk 1.0.4 → 1.1.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.
- package/README.md +277 -53
- package/dist/browser.d.ts +0 -15
- package/dist/caspay.min.js +2 -1
- package/dist/core/client.d.ts +1 -5
- package/dist/core/transfer.d.ts +8 -0
- package/dist/index.d.ts +7 -28
- package/dist/index.esm.js +460 -62
- package/dist/index.js +460 -62
- package/dist/resources/payments.d.ts +9 -23
- package/dist/resources/subscriptions.d.ts +7 -0
- package/dist/resources/wallet.d.ts +21 -0
- package/dist/types/index.d.ts +57 -31
- package/dist/version.d.ts +1 -0
- package/package.json +17 -4
package/dist/core/client.d.ts
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import type { CasPayConfig } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* HTTP Client for CasPay API
|
|
4
|
-
* Handles all API requests with authentication and error handling
|
|
5
|
-
*/
|
|
6
2
|
export declare class HttpClient {
|
|
7
3
|
private readonly baseUrl;
|
|
8
4
|
private apiKey;
|
|
9
5
|
private merchantId;
|
|
10
|
-
private readonly SDK_VERSION;
|
|
11
6
|
constructor(config: CasPayConfig);
|
|
12
7
|
request<T>(method: string, path: string, body?: Record<string, any>): Promise<T>;
|
|
13
8
|
getMerchantId(): string;
|
|
9
|
+
getBaseUrl(): string;
|
|
14
10
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Wallet } from '../resources/wallet';
|
|
2
|
+
import type { TransferParams, TransferResult } from '../types';
|
|
3
|
+
export declare class Transfer {
|
|
4
|
+
private wallet;
|
|
5
|
+
private apiBaseUrl;
|
|
6
|
+
constructor(wallet: Wallet, apiBaseUrl: string);
|
|
7
|
+
execute(params: TransferParams): Promise<TransferResult>;
|
|
8
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,17 @@
|
|
|
1
1
|
import { Payments } from './resources/payments';
|
|
2
|
+
import { Subscriptions } from './resources/subscriptions';
|
|
3
|
+
import { Wallet } from './resources/wallet';
|
|
2
4
|
import type { CasPayConfig } from './types';
|
|
3
|
-
/**
|
|
4
|
-
* CasPay SDK
|
|
5
|
-
* Official JavaScript/TypeScript SDK for CasPay payment gateway
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```typescript
|
|
9
|
-
* import CasPay from '@caspay/sdk';
|
|
10
|
-
*
|
|
11
|
-
* const caspay = new CasPay({
|
|
12
|
-
* apiKey: 'cp_live_...',
|
|
13
|
-
* merchantId: 'MERCH_...'
|
|
14
|
-
* });
|
|
15
|
-
*
|
|
16
|
-
* const payment = await caspay.payments.create({
|
|
17
|
-
* senderAddress: '0x123...',
|
|
18
|
-
* productId: 'prod_abc',
|
|
19
|
-
* amount: 100
|
|
20
|
-
* });
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
5
|
export default class CasPay {
|
|
24
|
-
/** Payments resource for creating and managing payments */
|
|
25
6
|
payments: Payments;
|
|
7
|
+
subscriptions: Subscriptions;
|
|
8
|
+
wallet: Wallet;
|
|
26
9
|
private client;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* @param config - SDK configuration
|
|
30
|
-
*/
|
|
10
|
+
private transfer;
|
|
11
|
+
private config;
|
|
31
12
|
constructor(config: CasPayConfig);
|
|
32
|
-
/**
|
|
33
|
-
* Get SDK version
|
|
34
|
-
*/
|
|
35
13
|
static get version(): string;
|
|
14
|
+
getConfig(): CasPayConfig;
|
|
36
15
|
}
|
|
37
16
|
export { CasPay };
|
|
38
17
|
export * from './types';
|
package/dist/index.esm.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { PublicKey, ExecutableDeployItem, TransferDeployItem, DeployHeader, Deploy } from 'casper-js-sdk';
|
|
2
|
+
|
|
3
|
+
const SDK_VERSION = '1.1.1';
|
|
4
|
+
|
|
5
5
|
class HttpClient {
|
|
6
6
|
constructor(config) {
|
|
7
|
-
this.baseUrl = 'https://caspay.link/api';
|
|
8
|
-
this.SDK_VERSION = '1.0.4';
|
|
9
7
|
this.apiKey = config.apiKey;
|
|
10
8
|
this.merchantId = config.merchantId;
|
|
11
|
-
|
|
9
|
+
this.baseUrl = config.baseUrl || 'https://caspay.link/api';
|
|
12
10
|
if (!this.apiKey) {
|
|
13
11
|
throw new Error('CasPay SDK: apiKey is required');
|
|
14
12
|
}
|
|
@@ -24,8 +22,8 @@ class HttpClient {
|
|
|
24
22
|
headers: {
|
|
25
23
|
'Content-Type': 'application/json',
|
|
26
24
|
'X-CasPay-Key': this.apiKey,
|
|
27
|
-
'X-CasPay-SDK-Version':
|
|
28
|
-
'User-Agent': `CasPay-SDK-JS/${
|
|
25
|
+
'X-CasPay-SDK-Version': SDK_VERSION,
|
|
26
|
+
'User-Agent': `CasPay-SDK-JS/${SDK_VERSION}`,
|
|
29
27
|
},
|
|
30
28
|
body: body ? JSON.stringify(body) : undefined,
|
|
31
29
|
});
|
|
@@ -41,11 +39,9 @@ class HttpClient {
|
|
|
41
39
|
return data;
|
|
42
40
|
}
|
|
43
41
|
catch (error) {
|
|
44
|
-
// Re-throw CasPay errors
|
|
45
42
|
if (error.error && error.code) {
|
|
46
43
|
throw error;
|
|
47
44
|
}
|
|
48
|
-
// Wrap network errors
|
|
49
45
|
throw {
|
|
50
46
|
error: error.message || 'Network error',
|
|
51
47
|
code: 'NETWORK_ERROR',
|
|
@@ -56,35 +52,126 @@ class HttpClient {
|
|
|
56
52
|
getMerchantId() {
|
|
57
53
|
return this.merchantId;
|
|
58
54
|
}
|
|
55
|
+
getBaseUrl() {
|
|
56
|
+
return this.baseUrl;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const CSPR_TO_MOTES = 1000000000;
|
|
61
|
+
const DEFAULT_PAYMENT_AMOUNT = '100000000';
|
|
62
|
+
class Transfer {
|
|
63
|
+
constructor(wallet, apiBaseUrl) {
|
|
64
|
+
this.wallet = wallet;
|
|
65
|
+
this.apiBaseUrl = apiBaseUrl;
|
|
66
|
+
}
|
|
67
|
+
async execute(params) {
|
|
68
|
+
const senderAddress = await this.wallet.getAddress();
|
|
69
|
+
if (!senderAddress) {
|
|
70
|
+
const error = {
|
|
71
|
+
code: 'WALLET_NOT_FOUND',
|
|
72
|
+
message: 'Please connect your wallet first.',
|
|
73
|
+
};
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
const provider = this.wallet.getProvider();
|
|
77
|
+
if (!provider) {
|
|
78
|
+
const error = {
|
|
79
|
+
code: 'WALLET_NOT_FOUND',
|
|
80
|
+
message: 'Wallet provider not available.',
|
|
81
|
+
};
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
const amountInMotes = Math.floor(params.amount * CSPR_TO_MOTES).toString();
|
|
85
|
+
const network = this.wallet.getNetwork();
|
|
86
|
+
const transferId = Date.now();
|
|
87
|
+
try {
|
|
88
|
+
const senderPublicKey = PublicKey.fromHex(senderAddress);
|
|
89
|
+
const recipientPublicKey = PublicKey.fromHex(params.recipientAddress);
|
|
90
|
+
const session = new ExecutableDeployItem();
|
|
91
|
+
session.transfer = TransferDeployItem.newTransfer(amountInMotes, recipientPublicKey, undefined, transferId);
|
|
92
|
+
const payment = ExecutableDeployItem.standardPayment(DEFAULT_PAYMENT_AMOUNT);
|
|
93
|
+
const deployHeader = DeployHeader.default();
|
|
94
|
+
deployHeader.account = senderPublicKey;
|
|
95
|
+
deployHeader.chainName = network;
|
|
96
|
+
const deploy = Deploy.makeDeploy(deployHeader, payment, session);
|
|
97
|
+
const deployJson = Deploy.toJSON(deploy);
|
|
98
|
+
const signResult = await provider.sign(JSON.stringify(deployJson), senderAddress);
|
|
99
|
+
if (signResult.cancelled) {
|
|
100
|
+
const error = {
|
|
101
|
+
code: 'TRANSFER_REJECTED',
|
|
102
|
+
message: 'Transfer was cancelled by the user.',
|
|
103
|
+
};
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
const algorithmTag = senderAddress.substring(0, 2);
|
|
107
|
+
const signatureHex = typeof signResult.signature === 'string'
|
|
108
|
+
? signResult.signature
|
|
109
|
+
: Array.from(signResult.signature)
|
|
110
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
111
|
+
.join('');
|
|
112
|
+
const signatureWithTag = algorithmTag + signatureHex;
|
|
113
|
+
const signedDeployJson = Deploy.toJSON(deploy);
|
|
114
|
+
signedDeployJson.approvals = [
|
|
115
|
+
{
|
|
116
|
+
signer: senderAddress,
|
|
117
|
+
signature: signatureWithTag,
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
const isMainnet = network === 'casper';
|
|
121
|
+
const rpcProxyUrl = `${this.apiBaseUrl}/rpc`;
|
|
122
|
+
const response = await fetch(rpcProxyUrl, {
|
|
123
|
+
method: 'POST',
|
|
124
|
+
headers: {
|
|
125
|
+
'Content-Type': 'application/json',
|
|
126
|
+
},
|
|
127
|
+
body: JSON.stringify({
|
|
128
|
+
deploy: signedDeployJson,
|
|
129
|
+
network: isMainnet ? 'mainnet' : 'testnet',
|
|
130
|
+
}),
|
|
131
|
+
});
|
|
132
|
+
const result = await response.json();
|
|
133
|
+
if (!response.ok || result.error) {
|
|
134
|
+
throw new Error(result.error || 'RPC request failed');
|
|
135
|
+
}
|
|
136
|
+
const deployHash = result.deploy_hash;
|
|
137
|
+
return {
|
|
138
|
+
deployHash,
|
|
139
|
+
senderAddress,
|
|
140
|
+
recipientAddress: params.recipientAddress,
|
|
141
|
+
amount: params.amount,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
if (error.code === 'TRANSFER_REJECTED') {
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
if (error.cancelled || error.code === 2 || error.message?.includes('rejected') || error.message?.includes('cancel')) {
|
|
149
|
+
const walletError = {
|
|
150
|
+
code: 'TRANSFER_REJECTED',
|
|
151
|
+
message: 'Transfer was cancelled by the user.',
|
|
152
|
+
};
|
|
153
|
+
throw walletError;
|
|
154
|
+
}
|
|
155
|
+
const walletError = {
|
|
156
|
+
code: 'NETWORK_ERROR',
|
|
157
|
+
message: error.message || 'Failed to execute transfer.',
|
|
158
|
+
};
|
|
159
|
+
throw walletError;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
59
162
|
}
|
|
60
163
|
|
|
61
|
-
/**
|
|
62
|
-
* Payments Resource
|
|
63
|
-
* Handle payment creation and verification
|
|
64
|
-
*/
|
|
65
164
|
class Payments {
|
|
66
165
|
constructor(client) {
|
|
166
|
+
this.wallet = null;
|
|
167
|
+
this.transfer = null;
|
|
67
168
|
this.client = client;
|
|
68
169
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
* @throws {CasPayError} If payment creation fails
|
|
75
|
-
*
|
|
76
|
-
* @example
|
|
77
|
-
* ```typescript
|
|
78
|
-
* const payment = await caspay.payments.create({
|
|
79
|
-
* senderAddress: '0x123...',
|
|
80
|
-
* productId: 'prod_abc123',
|
|
81
|
-
* amount: 100,
|
|
82
|
-
* currency: 'USD'
|
|
83
|
-
* });
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
async create(params) {
|
|
87
|
-
// Validate required fields
|
|
170
|
+
setWallet(wallet, transfer) {
|
|
171
|
+
this.wallet = wallet;
|
|
172
|
+
this.transfer = transfer;
|
|
173
|
+
}
|
|
174
|
+
async recordPayment(params) {
|
|
88
175
|
if (!params.senderAddress) {
|
|
89
176
|
throw {
|
|
90
177
|
error: 'senderAddress is required',
|
|
@@ -117,42 +204,353 @@ class Payments {
|
|
|
117
204
|
};
|
|
118
205
|
return this.client.request('POST', '/v1/payments/record', payload);
|
|
119
206
|
}
|
|
207
|
+
async recordSubscription(params) {
|
|
208
|
+
if (!params.subscriptionPlanId) {
|
|
209
|
+
throw {
|
|
210
|
+
error: 'subscriptionPlanId is required for subscription recording',
|
|
211
|
+
code: 'INVALID_PARAMS',
|
|
212
|
+
status: 400,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
return this.recordPayment(params);
|
|
216
|
+
}
|
|
217
|
+
async makePayment(params) {
|
|
218
|
+
if (!this.wallet || !this.transfer) {
|
|
219
|
+
throw {
|
|
220
|
+
error: 'Wallet not initialized. Make sure to use the SDK in browser environment.',
|
|
221
|
+
code: 'WALLET_NOT_INITIALIZED',
|
|
222
|
+
status: 500,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (!params.amount || params.amount <= 0) {
|
|
226
|
+
throw {
|
|
227
|
+
error: 'amount must be greater than 0',
|
|
228
|
+
code: 'INVALID_PARAMS',
|
|
229
|
+
status: 400,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
if (!params.productId && !params.subscriptionPlanId) {
|
|
233
|
+
throw {
|
|
234
|
+
error: 'Either productId or subscriptionPlanId is required',
|
|
235
|
+
code: 'INVALID_PARAMS',
|
|
236
|
+
status: 400,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
const isConnected = await this.wallet.isConnected();
|
|
241
|
+
if (!isConnected) {
|
|
242
|
+
await this.wallet.connect();
|
|
243
|
+
}
|
|
244
|
+
const senderAddress = await this.wallet.getAddress();
|
|
245
|
+
if (!senderAddress) {
|
|
246
|
+
throw {
|
|
247
|
+
error: 'Failed to get wallet address',
|
|
248
|
+
code: 'WALLET_ERROR',
|
|
249
|
+
status: 500,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
const merchantWalletAddress = this.wallet.getMerchantWalletAddress();
|
|
253
|
+
const transferResult = await this.transfer.execute({
|
|
254
|
+
recipientAddress: merchantWalletAddress,
|
|
255
|
+
amount: params.amount
|
|
256
|
+
});
|
|
257
|
+
try {
|
|
258
|
+
const paymentRecord = await this.recordPayment({
|
|
259
|
+
senderAddress: senderAddress,
|
|
260
|
+
transactionHash: transferResult.deployHash,
|
|
261
|
+
productId: params.productId,
|
|
262
|
+
subscriptionPlanId: params.subscriptionPlanId,
|
|
263
|
+
amount: params.amount,
|
|
264
|
+
currency: params.currency || 'CSPR',
|
|
265
|
+
});
|
|
266
|
+
return {
|
|
267
|
+
success: true,
|
|
268
|
+
transactionHash: transferResult.deployHash,
|
|
269
|
+
payment: paymentRecord,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
catch (recordError) {
|
|
273
|
+
return {
|
|
274
|
+
success: true,
|
|
275
|
+
transactionHash: transferResult.deployHash,
|
|
276
|
+
error: `Payment transferred but recording failed: ${recordError.error || recordError.message}`,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
return {
|
|
282
|
+
success: false,
|
|
283
|
+
transactionHash: '',
|
|
284
|
+
error: error.message || error.error || 'Payment failed',
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
class Subscriptions {
|
|
291
|
+
constructor(client) {
|
|
292
|
+
this.client = client;
|
|
293
|
+
}
|
|
294
|
+
async checkStatus(params) {
|
|
295
|
+
if (!params.subscriberAddress) {
|
|
296
|
+
throw {
|
|
297
|
+
error: 'subscriberAddress is required',
|
|
298
|
+
code: 'INVALID_PARAMS',
|
|
299
|
+
status: 400,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
const merchantId = this.client.getMerchantId();
|
|
303
|
+
let url = `/v1/subscriptions/check/?merchant_id=${merchantId}&subscriber=${params.subscriberAddress}`;
|
|
304
|
+
if (params.planId) {
|
|
305
|
+
url += `&plan_id=${params.planId}`;
|
|
306
|
+
}
|
|
307
|
+
return this.client.request('GET', url);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const CASPER_WALLET_INSTALL_URL = 'https://www.casperwallet.io/';
|
|
312
|
+
class Wallet {
|
|
313
|
+
constructor(config) {
|
|
314
|
+
this.provider = null;
|
|
315
|
+
this.connected = false;
|
|
316
|
+
this.activeAddress = null;
|
|
317
|
+
this.config = config;
|
|
318
|
+
this.initProvider();
|
|
319
|
+
}
|
|
320
|
+
initProvider() {
|
|
321
|
+
if (typeof window === 'undefined')
|
|
322
|
+
return;
|
|
323
|
+
const CasperWalletProvider = window.CasperWalletProvider;
|
|
324
|
+
if (CasperWalletProvider) {
|
|
325
|
+
this.provider = CasperWalletProvider({ timeout: 30 * 60 * 1000 });
|
|
326
|
+
this.setupEventListeners();
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
setupEventListeners() {
|
|
330
|
+
if (typeof window === 'undefined')
|
|
331
|
+
return;
|
|
332
|
+
window.addEventListener('casper-wallet:connected', (event) => {
|
|
333
|
+
try {
|
|
334
|
+
const state = JSON.parse(event.detail);
|
|
335
|
+
this.connected = true;
|
|
336
|
+
this.activeAddress = state.activeKey || null;
|
|
337
|
+
}
|
|
338
|
+
catch (e) {
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
window.addEventListener('casper-wallet:disconnected', () => {
|
|
342
|
+
this.connected = false;
|
|
343
|
+
this.activeAddress = null;
|
|
344
|
+
});
|
|
345
|
+
window.addEventListener('casper-wallet:activeKeyChanged', (event) => {
|
|
346
|
+
try {
|
|
347
|
+
const state = JSON.parse(event.detail);
|
|
348
|
+
this.activeAddress = state.activeKey || null;
|
|
349
|
+
}
|
|
350
|
+
catch (e) {
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
window.addEventListener('casper-wallet:locked', () => {
|
|
354
|
+
this.connected = false;
|
|
355
|
+
});
|
|
356
|
+
window.addEventListener('casper-wallet:unlocked', async () => {
|
|
357
|
+
if (this.provider) {
|
|
358
|
+
try {
|
|
359
|
+
const isConnected = await this.provider.isConnected();
|
|
360
|
+
this.connected = isConnected;
|
|
361
|
+
if (isConnected) {
|
|
362
|
+
this.activeAddress = await this.provider.getActivePublicKey();
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch (e) {
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
isAvailable() {
|
|
371
|
+
return typeof window !== 'undefined' && !!window.CasperWalletProvider;
|
|
372
|
+
}
|
|
373
|
+
async isConnected() {
|
|
374
|
+
if (!this.provider) {
|
|
375
|
+
this.connected = false;
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
try {
|
|
379
|
+
const connected = await this.provider.isConnected();
|
|
380
|
+
this.connected = connected;
|
|
381
|
+
return connected;
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
this.connected = false;
|
|
385
|
+
if (error.code === 1) {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
async connect() {
|
|
392
|
+
if (!this.isAvailable()) {
|
|
393
|
+
const error = {
|
|
394
|
+
code: 'WALLET_NOT_FOUND',
|
|
395
|
+
message: 'Casper Wallet extension not found. Please install it first.',
|
|
396
|
+
installUrl: CASPER_WALLET_INSTALL_URL,
|
|
397
|
+
};
|
|
398
|
+
throw error;
|
|
399
|
+
}
|
|
400
|
+
if (!this.provider) {
|
|
401
|
+
this.initProvider();
|
|
402
|
+
}
|
|
403
|
+
if (!this.provider) {
|
|
404
|
+
const error = {
|
|
405
|
+
code: 'WALLET_NOT_FOUND',
|
|
406
|
+
message: 'Failed to initialize Casper Wallet provider.',
|
|
407
|
+
installUrl: CASPER_WALLET_INSTALL_URL,
|
|
408
|
+
};
|
|
409
|
+
throw error;
|
|
410
|
+
}
|
|
411
|
+
try {
|
|
412
|
+
const connected = await this.provider.requestConnection();
|
|
413
|
+
if (!connected) {
|
|
414
|
+
const error = {
|
|
415
|
+
code: 'CONNECTION_REJECTED',
|
|
416
|
+
message: 'Wallet connection was rejected by the user.',
|
|
417
|
+
};
|
|
418
|
+
throw error;
|
|
419
|
+
}
|
|
420
|
+
this.connected = true;
|
|
421
|
+
this.activeAddress = await this.provider.getActivePublicKey();
|
|
422
|
+
if (!this.activeAddress) {
|
|
423
|
+
const error = {
|
|
424
|
+
code: 'UNKNOWN_ERROR',
|
|
425
|
+
message: 'Failed to get wallet address after connection.',
|
|
426
|
+
};
|
|
427
|
+
throw error;
|
|
428
|
+
}
|
|
429
|
+
return this.activeAddress;
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
if (error.code === 'CONNECTION_REJECTED') {
|
|
433
|
+
throw error;
|
|
434
|
+
}
|
|
435
|
+
if (error.code === 1) {
|
|
436
|
+
const walletError = {
|
|
437
|
+
code: 'WALLET_LOCKED',
|
|
438
|
+
message: 'Wallet is locked. Please unlock your Casper Wallet and try again.',
|
|
439
|
+
};
|
|
440
|
+
throw walletError;
|
|
441
|
+
}
|
|
442
|
+
const walletError = {
|
|
443
|
+
code: 'UNKNOWN_ERROR',
|
|
444
|
+
message: error.message || 'Failed to connect to wallet.',
|
|
445
|
+
};
|
|
446
|
+
throw walletError;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
async disconnect() {
|
|
450
|
+
if (this.provider) {
|
|
451
|
+
try {
|
|
452
|
+
await this.provider.disconnectFromSite();
|
|
453
|
+
}
|
|
454
|
+
catch (e) {
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
this.connected = false;
|
|
458
|
+
this.activeAddress = null;
|
|
459
|
+
}
|
|
460
|
+
async getAddress() {
|
|
461
|
+
if (!this.provider) {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
try {
|
|
465
|
+
const isConnected = await this.isConnected();
|
|
466
|
+
if (!isConnected) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
this.activeAddress = await this.provider.getActivePublicKey();
|
|
470
|
+
return this.activeAddress;
|
|
471
|
+
}
|
|
472
|
+
catch (error) {
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
getInfo() {
|
|
477
|
+
return {
|
|
478
|
+
isConnected: this.connected,
|
|
479
|
+
address: this.activeAddress,
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
async getState() {
|
|
483
|
+
const connected = await this.isConnected();
|
|
484
|
+
const address = connected ? await this.getAddress() : null;
|
|
485
|
+
return {
|
|
486
|
+
connected,
|
|
487
|
+
address,
|
|
488
|
+
locked: !connected && this.isAvailable(),
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
getProvider() {
|
|
492
|
+
return this.provider;
|
|
493
|
+
}
|
|
494
|
+
getMerchantWalletAddress() {
|
|
495
|
+
return this.config.walletAddress;
|
|
496
|
+
}
|
|
497
|
+
getNetwork() {
|
|
498
|
+
return this.config.network === 'mainnet' ? 'casper' : 'casper-test';
|
|
499
|
+
}
|
|
500
|
+
async signDeploy(deploy) {
|
|
501
|
+
if (!this.provider) {
|
|
502
|
+
const error = {
|
|
503
|
+
code: 'WALLET_NOT_FOUND',
|
|
504
|
+
message: 'Casper Wallet not available.',
|
|
505
|
+
installUrl: CASPER_WALLET_INSTALL_URL,
|
|
506
|
+
};
|
|
507
|
+
throw error;
|
|
508
|
+
}
|
|
509
|
+
const isConnected = await this.isConnected();
|
|
510
|
+
if (!isConnected) {
|
|
511
|
+
await this.connect();
|
|
512
|
+
}
|
|
513
|
+
try {
|
|
514
|
+
const deployJson = JSON.stringify(deploy);
|
|
515
|
+
const signature = await this.provider.sign(deployJson, this.activeAddress);
|
|
516
|
+
return signature;
|
|
517
|
+
}
|
|
518
|
+
catch (error) {
|
|
519
|
+
if (error.code === 2 || error.message?.includes('rejected') || error.message?.includes('cancelled')) {
|
|
520
|
+
const walletError = {
|
|
521
|
+
code: 'TRANSFER_REJECTED',
|
|
522
|
+
message: 'Transaction was rejected by the user.',
|
|
523
|
+
};
|
|
524
|
+
throw walletError;
|
|
525
|
+
}
|
|
526
|
+
const walletError = {
|
|
527
|
+
code: 'UNKNOWN_ERROR',
|
|
528
|
+
message: error.message || 'Failed to sign deploy.',
|
|
529
|
+
};
|
|
530
|
+
throw walletError;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
120
533
|
}
|
|
121
534
|
|
|
122
|
-
/**
|
|
123
|
-
* CasPay SDK
|
|
124
|
-
* Official JavaScript/TypeScript SDK for CasPay payment gateway
|
|
125
|
-
*
|
|
126
|
-
* @example
|
|
127
|
-
* ```typescript
|
|
128
|
-
* import CasPay from '@caspay/sdk';
|
|
129
|
-
*
|
|
130
|
-
* const caspay = new CasPay({
|
|
131
|
-
* apiKey: 'cp_live_...',
|
|
132
|
-
* merchantId: 'MERCH_...'
|
|
133
|
-
* });
|
|
134
|
-
*
|
|
135
|
-
* const payment = await caspay.payments.create({
|
|
136
|
-
* senderAddress: '0x123...',
|
|
137
|
-
* productId: 'prod_abc',
|
|
138
|
-
* amount: 100
|
|
139
|
-
* });
|
|
140
|
-
* ```
|
|
141
|
-
*/
|
|
142
535
|
class CasPay {
|
|
143
|
-
/**
|
|
144
|
-
* Create a new CasPay SDK instance
|
|
145
|
-
* @param config - SDK configuration
|
|
146
|
-
*/
|
|
147
536
|
constructor(config) {
|
|
537
|
+
if (!config.walletAddress) {
|
|
538
|
+
throw new Error('CasPay SDK: walletAddress is required');
|
|
539
|
+
}
|
|
540
|
+
this.config = config;
|
|
148
541
|
this.client = new HttpClient(config);
|
|
542
|
+
this.wallet = new Wallet(config);
|
|
543
|
+
const apiBaseUrl = this.client.getBaseUrl();
|
|
544
|
+
this.transfer = new Transfer(this.wallet, apiBaseUrl);
|
|
149
545
|
this.payments = new Payments(this.client);
|
|
546
|
+
this.payments.setWallet(this.wallet, this.transfer);
|
|
547
|
+
this.subscriptions = new Subscriptions(this.client);
|
|
150
548
|
}
|
|
151
|
-
/**
|
|
152
|
-
* Get SDK version
|
|
153
|
-
*/
|
|
154
549
|
static get version() {
|
|
155
|
-
return
|
|
550
|
+
return SDK_VERSION;
|
|
551
|
+
}
|
|
552
|
+
getConfig() {
|
|
553
|
+
return { ...this.config };
|
|
156
554
|
}
|
|
157
555
|
}
|
|
158
556
|
|