@profullstack/coinpay 0.6.7 → 0.6.8

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/bin/coinpay.js CHANGED
@@ -119,6 +119,13 @@ function createClient() {
119
119
  return new CoinPayClient({ apiKey, baseUrl: getBaseUrl() });
120
120
  }
121
121
 
122
+ /**
123
+ * Create unauthenticated client for auth operations
124
+ */
125
+ function createUnauthenticatedClient() {
126
+ return new CoinPayClient({ baseUrl: getBaseUrl() });
127
+ }
128
+
122
129
  /**
123
130
  * Parse command line arguments
124
131
  */
@@ -171,6 +178,11 @@ ${colors.cyan}Commands:${colors.reset}
171
178
  set-url <base-url> Set custom API URL
172
179
  show Show current configuration
173
180
 
181
+ ${colors.bright}auth${colors.reset}
182
+ register Register new merchant account
183
+ login Login to merchant account
184
+ me Show current merchant info
185
+
174
186
  ${colors.bright}payment${colors.reset}
175
187
  create Create a new payment
176
188
  get <id> Get payment details
@@ -241,6 +253,8 @@ ${colors.cyan}Commands:${colors.reset}
241
253
  badge [did] Get embeddable reputation badge URL
242
254
  verify <id> Verify a credential
243
255
  revocations List revoked credentials
256
+ did claim Claim (auto-generate) a new DID
257
+ did me Show your current DID
244
258
  issuer register Register platform issuer (--name, --domain)
245
259
  issuer list List your platform issuers
246
260
  issuer rotate Rotate issuer API key (--id)
@@ -1715,6 +1729,136 @@ async function handleEscrow(subcommand, args, flags) {
1715
1729
  }
1716
1730
  }
1717
1731
 
1732
+ /**
1733
+ * Auth commands
1734
+ */
1735
+ async function handleAuth(subcommand, args, flags) {
1736
+ const config = loadConfig();
1737
+
1738
+ switch (subcommand) {
1739
+ case 'register': {
1740
+ const email = flags.email;
1741
+ const password = flags.password;
1742
+ const name = flags.name;
1743
+
1744
+ if (!email || !password) {
1745
+ print.error('Required: --email <email> --password <password>');
1746
+ print.info('Example: coinpay auth register --email user@example.com --password mysecret --name "My Company"');
1747
+ return;
1748
+ }
1749
+
1750
+ try {
1751
+ const client = createUnauthenticatedClient();
1752
+ const { registerMerchant } = await import('../src/auth.js');
1753
+ const result = await registerMerchant(client, { email, password, name });
1754
+
1755
+ if (result.success) {
1756
+ // Store the JWT token in config
1757
+ config.jwtToken = result.token;
1758
+ saveConfig(config);
1759
+
1760
+ print.success('Registration successful!');
1761
+ print.info(`Merchant ID: ${result.merchant.id}`);
1762
+ print.info(`Email: ${result.merchant.email}`);
1763
+ if (result.merchant.name) {
1764
+ print.info(`Name: ${result.merchant.name}`);
1765
+ }
1766
+ print.success('JWT token saved to config');
1767
+ } else {
1768
+ print.error(result.error || 'Registration failed');
1769
+ }
1770
+
1771
+ if (flags.json) {
1772
+ print.json(result);
1773
+ }
1774
+ } catch (error) {
1775
+ print.error(error.message);
1776
+ }
1777
+ break;
1778
+ }
1779
+
1780
+ case 'login': {
1781
+ const email = flags.email;
1782
+ const password = flags.password;
1783
+
1784
+ if (!email || !password) {
1785
+ print.error('Required: --email <email> --password <password>');
1786
+ print.info('Example: coinpay auth login --email user@example.com --password mysecret');
1787
+ return;
1788
+ }
1789
+
1790
+ try {
1791
+ const client = createUnauthenticatedClient();
1792
+ const { loginMerchant } = await import('../src/auth.js');
1793
+ const result = await loginMerchant(client, { email, password });
1794
+
1795
+ if (result.success) {
1796
+ // Store the JWT token in config
1797
+ config.jwtToken = result.token;
1798
+ saveConfig(config);
1799
+
1800
+ print.success('Login successful!');
1801
+ print.info(`Merchant ID: ${result.merchant.id}`);
1802
+ print.info(`Email: ${result.merchant.email}`);
1803
+ if (result.merchant.name) {
1804
+ print.info(`Name: ${result.merchant.name}`);
1805
+ }
1806
+ print.success('JWT token saved to config');
1807
+ } else {
1808
+ print.error(result.error || 'Login failed');
1809
+ }
1810
+
1811
+ if (flags.json) {
1812
+ print.json(result);
1813
+ }
1814
+ } catch (error) {
1815
+ print.error(error.message);
1816
+ }
1817
+ break;
1818
+ }
1819
+
1820
+ case 'me': {
1821
+ try {
1822
+ // Check if we have a JWT token
1823
+ const jwtToken = config.jwtToken;
1824
+ if (!jwtToken) {
1825
+ print.error('Not authenticated. Run: coinpay auth login');
1826
+ return;
1827
+ }
1828
+
1829
+ // Create client with JWT token instead of API key
1830
+ const client = new CoinPayClient({ apiKey: jwtToken, baseUrl: getBaseUrl() });
1831
+ const { getMe } = await import('../src/auth.js');
1832
+ const result = await getMe(client);
1833
+
1834
+ print.success('Current merchant:');
1835
+ print.info(`ID: ${result.id}`);
1836
+ print.info(`Email: ${result.email}`);
1837
+ if (result.name) {
1838
+ print.info(`Name: ${result.name}`);
1839
+ }
1840
+ print.info(`Created: ${result.created_at}`);
1841
+
1842
+ if (flags.json) {
1843
+ print.json(result);
1844
+ }
1845
+ } catch (error) {
1846
+ if (error.message.includes('401') || error.message.includes('403')) {
1847
+ print.error('Authentication failed. Please run: coinpay auth login');
1848
+ } else {
1849
+ print.error(error.message);
1850
+ }
1851
+ }
1852
+ break;
1853
+ }
1854
+
1855
+ default:
1856
+ print.error(`Unknown auth command: ${subcommand}`);
1857
+ print.info('Available: register, login, me');
1858
+ process.exit(1);
1859
+ }
1860
+ }
1861
+
1718
1862
  /**
1719
1863
  * Reputation commands
1720
1864
  */
@@ -1896,6 +2040,21 @@ async function handleReputation(subcommand, args, flags) {
1896
2040
  print.error(result.error || 'Failed to link DID');
1897
2041
  }
1898
2042
 
2043
+ if (flags.json) print.json(result);
2044
+ } else if (didSubcommand === 'me') {
2045
+ // Show current DID
2046
+ const { getMyDid } = await import('../src/reputation.js');
2047
+ const result = await getMyDid(client);
2048
+
2049
+ if (result.did) {
2050
+ print.success(`Your DID: ${result.did}`);
2051
+ console.log(` Public Key: ${result.public_key}`);
2052
+ console.log(` Verified: ${result.verified}`);
2053
+ console.log(` Created: ${result.created_at}`);
2054
+ } else {
2055
+ print.info('No DID found. Run: coinpay reputation did claim');
2056
+ }
2057
+
1899
2058
  if (flags.json) print.json(result);
1900
2059
  } else {
1901
2060
  // Default: show current DID
@@ -2449,6 +2608,10 @@ async function main() {
2449
2608
  await handleCard(subcommand, args, flags);
2450
2609
  break;
2451
2610
 
2611
+ case 'auth':
2612
+ await handleAuth(subcommand, args, flags);
2613
+ break;
2614
+
2452
2615
  case 'reputation':
2453
2616
  await handleReputation(subcommand, args, flags);
2454
2617
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@profullstack/coinpay",
3
- "version": "0.6.7",
3
+ "version": "0.6.8",
4
4
  "description": "CoinPay SDK & CLI — Accept cryptocurrency payments (BTC, ETH, SOL, POL, BCH, USDC) with wallet and swap support",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/auth.d.ts ADDED
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Auth SDK Module Types
3
+ */
4
+
5
+ import { CoinPayClient } from './client.js';
6
+
7
+ /**
8
+ * Merchant object returned from auth operations
9
+ */
10
+ export interface Merchant {
11
+ id: string;
12
+ email: string;
13
+ name?: string;
14
+ created_at: string;
15
+ updated_at?: string;
16
+ [key: string]: any;
17
+ }
18
+
19
+ /**
20
+ * Auth response for register/login
21
+ */
22
+ export interface AuthResponse {
23
+ success: boolean;
24
+ merchant: Merchant;
25
+ token: string;
26
+ }
27
+
28
+ /**
29
+ * Register params
30
+ */
31
+ export interface RegisterParams {
32
+ email: string;
33
+ password: string;
34
+ name?: string;
35
+ }
36
+
37
+ /**
38
+ * Login params
39
+ */
40
+ export interface LoginParams {
41
+ email: string;
42
+ password: string;
43
+ }
44
+
45
+ /**
46
+ * Register a new merchant account
47
+ * @param client - CoinPay client (can be unauthenticated)
48
+ * @param params - Registration parameters
49
+ * @returns Promise with registration response
50
+ */
51
+ export function registerMerchant(
52
+ client: CoinPayClient,
53
+ params: RegisterParams
54
+ ): Promise<AuthResponse>;
55
+
56
+ /**
57
+ * Login to merchant account
58
+ * @param client - CoinPay client (can be unauthenticated)
59
+ * @param params - Login parameters
60
+ * @returns Promise with login response
61
+ */
62
+ export function loginMerchant(
63
+ client: CoinPayClient,
64
+ params: LoginParams
65
+ ): Promise<AuthResponse>;
66
+
67
+ /**
68
+ * Get current authenticated merchant info
69
+ * @param client - Authenticated CoinPay client
70
+ * @returns Promise with merchant information
71
+ */
72
+ export function getMe(client: CoinPayClient): Promise<Merchant>;
package/src/auth.js ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Auth SDK Module
3
+ *
4
+ * Authentication functions for registration, login, and merchant management.
5
+ *
6
+ * @example
7
+ * import { CoinPayClient } from '@profullstack/coinpay';
8
+ * import { registerMerchant, loginMerchant, getMe } from '@profullstack/coinpay/auth';
9
+ */
10
+
11
+ /**
12
+ * Register a new merchant account
13
+ * @param {import('./client.js').CoinPayClient} client - CoinPay client (can be unauthenticated)
14
+ * @param {Object} params
15
+ * @param {string} params.email - Merchant email
16
+ * @param {string} params.password - Account password
17
+ * @param {string} [params.name] - Optional merchant name
18
+ * @returns {Promise<Object>} { success: boolean, merchant: Object, token: string }
19
+ */
20
+ export async function registerMerchant(client, { email, password, name }) {
21
+ return client.requestUnauthenticated('/auth/register', {
22
+ method: 'POST',
23
+ body: JSON.stringify({
24
+ email,
25
+ password,
26
+ name,
27
+ }),
28
+ });
29
+ }
30
+
31
+ /**
32
+ * Login to merchant account
33
+ * @param {import('./client.js').CoinPayClient} client - CoinPay client (can be unauthenticated)
34
+ * @param {Object} params
35
+ * @param {string} params.email - Merchant email
36
+ * @param {string} params.password - Account password
37
+ * @returns {Promise<Object>} { success: boolean, merchant: Object, token: string }
38
+ */
39
+ export async function loginMerchant(client, { email, password }) {
40
+ return client.requestUnauthenticated('/auth/login', {
41
+ method: 'POST',
42
+ body: JSON.stringify({
43
+ email,
44
+ password,
45
+ }),
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Get current authenticated merchant info
51
+ * @param {import('./client.js').CoinPayClient} client - Authenticated CoinPay client
52
+ * @returns {Promise<Object>} Merchant information
53
+ */
54
+ export async function getMe(client) {
55
+ return client.request('/auth/me', {
56
+ method: 'POST',
57
+ });
58
+ }
package/src/client.js CHANGED
@@ -16,15 +16,11 @@ export class CoinPayClient {
16
16
  /**
17
17
  * Create a new CoinPay client
18
18
  * @param {Object} options - Client options
19
- * @param {string} options.apiKey - Your CoinPay API key
19
+ * @param {string} [options.apiKey] - Your CoinPay API key (optional for auth operations)
20
20
  * @param {string} [options.baseUrl] - API base URL (default: https://coinpayportal.com/api)
21
21
  * @param {number} [options.timeout] - Request timeout in ms (default: 30000)
22
22
  */
23
- constructor({ apiKey, baseUrl = DEFAULT_BASE_URL, timeout = 30000 }) {
24
- if (!apiKey) {
25
- throw new Error('API key is required');
26
- }
27
-
23
+ constructor({ apiKey, baseUrl = DEFAULT_BASE_URL, timeout = 30000 } = {}) {
28
24
  this.#apiKey = apiKey;
29
25
  this.#baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
30
26
  this.#timeout = timeout;
@@ -37,6 +33,10 @@ export class CoinPayClient {
37
33
  * @returns {Promise<Object>} API response
38
34
  */
39
35
  async request(endpoint, options = {}) {
36
+ if (!this.#apiKey) {
37
+ throw new Error('API key is required for authenticated requests. Use requestUnauthenticated() for registration/login.');
38
+ }
39
+
40
40
  const url = `${this.#baseUrl}${endpoint}`;
41
41
  const controller = new AbortController();
42
42
  const timeoutId = setTimeout(() => controller.abort(), this.#timeout);
@@ -72,6 +72,47 @@ export class CoinPayClient {
72
72
  }
73
73
  }
74
74
 
75
+ /**
76
+ * Make an unauthenticated API request (for registration/login)
77
+ * @param {string} endpoint - API endpoint
78
+ * @param {Object} [options] - Fetch options
79
+ * @returns {Promise<Object>} API response
80
+ */
81
+ async requestUnauthenticated(endpoint, options = {}) {
82
+ const url = `${this.#baseUrl}${endpoint}`;
83
+ const controller = new AbortController();
84
+ const timeoutId = setTimeout(() => controller.abort(), this.#timeout);
85
+
86
+ try {
87
+ const response = await fetch(url, {
88
+ ...options,
89
+ signal: controller.signal,
90
+ headers: {
91
+ 'Content-Type': 'application/json',
92
+ ...options.headers,
93
+ },
94
+ });
95
+
96
+ const data = await response.json();
97
+
98
+ if (!response.ok) {
99
+ const error = new Error(data.error || `HTTP ${response.status}`);
100
+ error.status = response.status;
101
+ error.response = data;
102
+ throw error;
103
+ }
104
+
105
+ return data;
106
+ } catch (error) {
107
+ if (error.name === 'AbortError') {
108
+ throw new Error(`Request timeout after ${this.#timeout}ms`);
109
+ }
110
+ throw error;
111
+ } finally {
112
+ clearTimeout(timeoutId);
113
+ }
114
+ }
115
+
75
116
  /**
76
117
  * Create a new payment
77
118
  *
package/src/index.js CHANGED
@@ -88,8 +88,18 @@ import {
88
88
  getBadgeUrl,
89
89
  verifyCredential,
90
90
  getRevocationList,
91
+ claimDid,
92
+ linkDid,
93
+ getMyDid,
91
94
  } from './reputation.js';
92
95
 
96
+ // Auth exports
97
+ import {
98
+ registerMerchant,
99
+ loginMerchant,
100
+ getMe,
101
+ } from './auth.js';
102
+
93
103
  import {
94
104
  SwapClient,
95
105
  SwapCoins,
@@ -216,8 +226,19 @@ export {
216
226
  submitReceipt,
217
227
  getReputation,
218
228
  getCredential,
229
+ getCredentials,
230
+ getReceipts,
231
+ getBadgeUrl,
219
232
  verifyCredential,
220
233
  getRevocationList,
234
+ claimDid,
235
+ linkDid,
236
+ getMyDid,
237
+
238
+ // Auth
239
+ registerMerchant,
240
+ loginMerchant,
241
+ getMe,
221
242
 
222
243
  // Webhook utilities
223
244
  verifyWebhookSignature,