@aboutcircles/sdk-invitations 0.1.10 → 0.1.11
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/dist/Invitations.d.ts +11 -1
- package/dist/Invitations.d.ts.map +1 -1
- package/dist/Invitations.js +455 -0
- package/dist/InviteFarm.d.ts +59 -0
- package/dist/InviteFarm.d.ts.map +1 -0
- package/dist/InviteFarm.js +123 -0
- package/dist/Referrals.js +129 -0
- package/dist/errors.js +69 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/types.d.ts +33 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { InvitationError } from "./errors";
|
|
2
|
+
/**
|
|
3
|
+
* Referrals service client for retrieving referral information
|
|
4
|
+
*
|
|
5
|
+
* The referrals backend enables Circles SDK users to query referral data:
|
|
6
|
+
* - Retrieve: Get referral info by private key (public)
|
|
7
|
+
* - List: Get all referrals created by authenticated user
|
|
8
|
+
*
|
|
9
|
+
* Note: Storing referrals is handled by Invitations.generateReferral()
|
|
10
|
+
*/
|
|
11
|
+
export class Referrals {
|
|
12
|
+
baseUrl;
|
|
13
|
+
getToken;
|
|
14
|
+
/**
|
|
15
|
+
* Create a new Referrals client
|
|
16
|
+
*
|
|
17
|
+
* @param baseUrl - The referrals service base URL (e.g., "https://referrals.circles.example")
|
|
18
|
+
* @param getToken - Optional function to get auth token for authenticated endpoints
|
|
19
|
+
*/
|
|
20
|
+
constructor(baseUrl, getToken) {
|
|
21
|
+
this.baseUrl = baseUrl;
|
|
22
|
+
this.getToken = getToken;
|
|
23
|
+
}
|
|
24
|
+
getBaseUrl() {
|
|
25
|
+
return this.baseUrl.endsWith("/")
|
|
26
|
+
? this.baseUrl.slice(0, -1)
|
|
27
|
+
: this.baseUrl;
|
|
28
|
+
}
|
|
29
|
+
async getAuthHeaders() {
|
|
30
|
+
if (!this.getToken) {
|
|
31
|
+
return { "Content-Type": "application/json" };
|
|
32
|
+
}
|
|
33
|
+
const token = await this.getToken();
|
|
34
|
+
return {
|
|
35
|
+
"Content-Type": "application/json",
|
|
36
|
+
Authorization: `Bearer ${token}`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Retrieve referral info by private key
|
|
41
|
+
*
|
|
42
|
+
* This is a public endpoint - no authentication required.
|
|
43
|
+
* Used by invitees to look up who invited them.
|
|
44
|
+
*
|
|
45
|
+
* @param privateKey - The referral private key
|
|
46
|
+
* @returns Referral info including inviter and status
|
|
47
|
+
* @throws InvitationError if referral not found or expired
|
|
48
|
+
*/
|
|
49
|
+
async retrieve(privateKey) {
|
|
50
|
+
try {
|
|
51
|
+
const url = `${this.getBaseUrl()}/referral/retrieve?key=${encodeURIComponent(privateKey)}`;
|
|
52
|
+
const response = await fetch(url);
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
let errorMessage = `HTTP error! status: ${response.status}`;
|
|
55
|
+
try {
|
|
56
|
+
const error = (await response.json());
|
|
57
|
+
errorMessage = error.error || errorMessage;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
errorMessage = response.statusText || errorMessage;
|
|
61
|
+
}
|
|
62
|
+
throw new InvitationError(errorMessage, {
|
|
63
|
+
code: 'INVITATION_RETRIEVE_FAILED',
|
|
64
|
+
source: 'INVITATIONS',
|
|
65
|
+
context: { status: response.status, url, privateKey }
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return response.json();
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (error instanceof InvitationError) {
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
throw new InvitationError(`Failed to retrieve referral: ${error instanceof Error ? error.message : 'Unknown error'}`, {
|
|
75
|
+
code: 'INVITATION_RETRIEVE_ERROR',
|
|
76
|
+
source: 'INVITATIONS',
|
|
77
|
+
cause: error,
|
|
78
|
+
context: { privateKey }
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* List all referrals created by the authenticated user
|
|
84
|
+
*
|
|
85
|
+
* Requires authentication - the user's address is extracted from the JWT token.
|
|
86
|
+
*
|
|
87
|
+
* @returns List of referrals with their status and metadata
|
|
88
|
+
* @throws InvitationError if not authenticated or request fails
|
|
89
|
+
*/
|
|
90
|
+
async listMine() {
|
|
91
|
+
if (!this.getToken) {
|
|
92
|
+
throw new InvitationError("Authentication required to list referrals", {
|
|
93
|
+
code: 'INVITATION_AUTH_REQUIRED',
|
|
94
|
+
source: 'INVITATIONS'
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const url = `${this.getBaseUrl()}/referral/my-referrals`;
|
|
99
|
+
const headers = await this.getAuthHeaders();
|
|
100
|
+
const response = await fetch(url, { headers });
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
let errorMessage = `HTTP error! status: ${response.status}`;
|
|
103
|
+
try {
|
|
104
|
+
const error = (await response.json());
|
|
105
|
+
errorMessage = error.error || errorMessage;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
errorMessage = response.statusText || errorMessage;
|
|
109
|
+
}
|
|
110
|
+
throw new InvitationError(errorMessage, {
|
|
111
|
+
code: 'INVITATION_LIST_FAILED',
|
|
112
|
+
source: 'INVITATIONS',
|
|
113
|
+
context: { status: response.status, url }
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return response.json();
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
if (error instanceof InvitationError) {
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
throw new InvitationError(`Failed to list referrals: ${error instanceof Error ? error.message : 'Unknown error'}`, {
|
|
123
|
+
code: 'INVITATION_LIST_ERROR',
|
|
124
|
+
source: 'INVITATIONS',
|
|
125
|
+
cause: error
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { CirclesError } from '@aboutcircles/sdk-utils';
|
|
2
|
+
/**
|
|
3
|
+
* Base error for invitations package
|
|
4
|
+
*/
|
|
5
|
+
export class InvitationError extends CirclesError {
|
|
6
|
+
constructor(message, options) {
|
|
7
|
+
super('InvitationError', message, { ...options, source: options?.source || 'INVITATIONS' });
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Error when no valid invitation path is found
|
|
11
|
+
*/
|
|
12
|
+
static noPathFound(from, to, reason) {
|
|
13
|
+
return new InvitationError(`No valid invitation path found from ${from} to ${to}. ${reason || 'The inviter may not have enough balance of the proxy inviter\'s token or there\'s no trust connection.'}`, {
|
|
14
|
+
code: 'INVITATION_NO_PATH',
|
|
15
|
+
source: 'PATHFINDING',
|
|
16
|
+
context: { from, to, reason },
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error when no proxy inviters are available
|
|
21
|
+
*/
|
|
22
|
+
static noProxyInviters(inviter) {
|
|
23
|
+
return new InvitationError(`No proxy inviters found for ${inviter}. The inviter must have mutual trust connections with users who are also trusted by the invitation module, and these users must have sufficient balance.`, {
|
|
24
|
+
code: 'INVITATION_NO_PROXY_INVITERS',
|
|
25
|
+
source: 'VALIDATION',
|
|
26
|
+
context: { inviter },
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Error when balance is insufficient for the requested invitations
|
|
31
|
+
*/
|
|
32
|
+
static insufficientBalance(requestedInvites, availableInvites, requested, available, from, to) {
|
|
33
|
+
const requestedCrc = Number(requested) / 1e18;
|
|
34
|
+
const availableCrc = Number(available) / 1e18;
|
|
35
|
+
return new InvitationError(`Insufficient balance for ${requestedInvites} invitation(s). Can only afford ${availableInvites} invitation(s). Requested: ${requestedCrc.toFixed(6)} CRC, Available: ${availableCrc.toFixed(6)} CRC.`, {
|
|
36
|
+
code: 'INVITATION_INSUFFICIENT_BALANCE',
|
|
37
|
+
source: 'VALIDATION',
|
|
38
|
+
context: {
|
|
39
|
+
from,
|
|
40
|
+
to,
|
|
41
|
+
requestedInvites,
|
|
42
|
+
availableInvites,
|
|
43
|
+
requested: requested.toString(),
|
|
44
|
+
available: available.toString(),
|
|
45
|
+
requestedCrc,
|
|
46
|
+
availableCrc,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Error when invitee is already registered in Circles Hub
|
|
52
|
+
*/
|
|
53
|
+
static inviteeAlreadyRegistered(inviter, invitee) {
|
|
54
|
+
return new InvitationError(`Invitee ${invitee} is already registered as a human in Circles Hub. Cannot invite an already registered user.`, {
|
|
55
|
+
code: 'INVITATION_INVITEE_ALREADY_REGISTERED',
|
|
56
|
+
source: 'VALIDATION',
|
|
57
|
+
context: { inviter, invitee },
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Error when no addresses are provided for invitation
|
|
62
|
+
*/
|
|
63
|
+
static noAddressesProvided() {
|
|
64
|
+
return new InvitationError('At least one address must be provided for invitation.', {
|
|
65
|
+
code: 'INVITATION_NO_ADDRESSES_PROVIDED',
|
|
66
|
+
source: 'VALIDATION',
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
|