@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 +163 -0
- package/package.json +1 -1
- package/src/auth.d.ts +72 -0
- package/src/auth.js +58 -0
- package/src/client.js +47 -6
- package/src/index.js +21 -0
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
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,
|