class Raida
There are two different files here. One is for Internet Browsers and the other is for Node.js programs.
Web Browser (in 'lib' folder)
The raidamail.min.js file contains the Raida class and other supporting libraries, such as Axios. The Raida class has functions that allow you to connect to RAIDAMail Cloud.
Node.js (in 'dist' folder)
The node.js repository and can be installed via npm install raidamailjs. It doesn't have libraries in it. (like axios) Libraries are installed by npm using dependency tree.
Table of Contents
Installing
Using npm:
$ npm install raidamailjs
Using html:
<script src="https://yourwebsite.com/dist/raidamailjs.web.js"></script>
Example
Browser:
rdata = {
'group_id' : 123,
'members': [
{
'sn':30,
'pr':'full',
},
{
'sn':31,
'pr':'modify',
},
{
'sn':32
},
]
}
let r = new RaidaMailJS({ timeout: 20000, debug: false })
r.apiGroupMembersCreate(rdata, (rIdx, state) => {
console.log("intermediate r"+rIdx+ " state="+state)
}).then(r => {
console.log("done")
console.log(r)
})
Node.js ES6
import RaidaMailJS from "raidamailjs"
let r = new RaidaMailJS()
r.apiGroupMembersCreate()
Node.js ES5
let RaidaMailJS = require('raidamailjs').default
let r = new RaidaMailJS()
RaidaMailJS
Here are the available config options for making requests. None of them is required.
let options = {
// The main domain for the RAIDA
domain : "cloudcoin.global",
// Prefix used to construct the final url
prefix : "raida",
// Protocol schema
protocol: "https",
// Read Timeout for HTTP requests in milliseconds
timeout: 10000,
// Debug. If set, an additional 'details' field will be set in the response data.
// The field contains a raw response from the RAIDA server
debug: false,
// RAIDA to query when we create SkywWallets
defaultRaidaForQuery: 7,
// DDNS service for SkyWallets
ddnsServer: "ddns.cloudcoin.global",
// Number of Failed Raida servers
maxFailedRaidas: 5,
// Key Length for AES encryption
keyLength: 4,
// Delete threshold
delete_threshold: 12,
// URL for getting a free coin
freeCoinURL: "https://cloudcoin.global/freecoin.php",
// Get My IP API
myIPURL: "https://ipapi.co/json/",
// Minimum password Length
minPasswordLength: 8
// Whether the Local Cache is enabled. Default true
cacheEnabled: true,
// Default expiration time is 86400
cacheExpirationSeconds: 86400
}
let raidaJS = new RaidaMailJS(options)
RaidaMailJS Api Methods: Methods that contact the RAIDA.
All methods are executed asynchronously and return Javascript Promise Object If there is an error with the input data the method returns null
Each API method has an optional callback
argument. If defined this function is called after each raida returns or fails. It helps to track the progress of the whole bunch of requests
let progress = 0
raidaJS.apiGroupMembersCreate(data, raidaNumber => {
console.log("RAIDA " + raidaNumber + " finished")
progress++
}).then(response => console.log(response))
Some functions may return 'failedSessions' array denoting RAIDA Servers that failed to validate the AN. Most likely the AN is invalid. The App must ask user for username and password and call apiRegister() again. The App may also store login and password in the Session Local Storage.
If 'failedSessions' array is empty, no actions should be taken
Set functions
raidaJS.setTimeout(15000)
raidaJS.setProtocol("http")
raidaJS.setDomain("raida.tech")
raidaJS.setDefaultNetworkNumber(2)
raidaJS.setDefaultRAIDA(7)
Get functions
// Returns the current set of the RAIDA URLs
raidaJS.getServers()
Generic Response Format
All the functions from RaidaMailJS return "status" field in the result. The "status" can be one of the ['done', 'error']
Error response structure:
{
// For errors this is always error
"status" : "error",
// Error Description
"errorText" : "ErrorDescription",
// Auxillary data
"errorData" : ""
}
'errorData' may contain a versioning array of 25 items. Each item shows the version number of the returned data. It might help finding errors in RAIDA synchronization.
Possible values of the versioning item:
undefined - RAIDA Server failed to respond
null - RAIDA Server didn't have versioning for this type of data
integer - Valid version number
Successfull response:
{
// Code
"code" : interger
// Status (Legacy)
"status" : "done",
// Rest dataa
...
}
Successfull responses may also include 'versions' object for the data. The keys of the object are IDs of the data and the values are arrays of 25 items. Each item has the same format as for errors:
undefined - RAIDA Server failed to respond
null - RAIDA Server didn't have versioning for this type of data
integer - Valid version number
Example for List Groups:
{
"status" : "done",
"versions" : {
"6C4B01B73970BFC7BADFF1502E1C4890": ["1622569919", "1622569919", "1622569919", undefined, undefined, "1622569919", "1622569919", null, null, "1622569919", "1622569919", undefined, "1622569919", "1622569919", "1622569919", "1622569919", null, null, "1622569919", "1622569919", "1622569919", "1622569919", "1622569919"],
"6C4B01B73970BFC7BADFF1502E1C4891": ["1622569919", "1622569919", "1622569919", undefined, undefined, "1622569919", "1622569919", null, null, "1622569919", "1622569919", undefined, "1622569919", "1622569919", "1622569919", "1622569919", null, null, "1622569919", "1622569919", "1622569919", "1622569919", "1622569919"]
}
}
Error Codes:
RaidaMailJS.ERR_NO_ERROR = 0x0
RaidaMailJS.ERR_COMMON = 0x2
RaidaMailJS.ERR_AUTH_FAILED = 0x3
RaidaMailJS.ERR_USERNAME_ALREADY_EXISTS = 0x4
RaidaMailJS.ERR_PARAM_INCORRECT_INPUT = 0x1001
RaidaMailJS.ERR_PARAM_INCORRECT_USERNAME = 0x1002
RaidaMailJS.ERR_PARAM_INCORRECT_PASSWORD = 0x1003
RaidaMailJS.ERR_PARAM_INCORRECT_EMAIL = 0x1004
RaidaMailJS.ERR_PARAM_INCORRECT_GROUP = 0x1005
RaidaMailJS.ERR_WRONG_HTTP_RESPONSE = 0x2001
RaidaMailJS.ERR_FAILED_RESPONSE = 0x2002
RaidaMailJS.ERR_NETWORK = 0x2003
Api Methods
apiAuth
The function takes a username and password and authenticates it on the Raida Mail servers. It saves fetched ANs in the Local State and returns them in the response. The application can save the ANs in the Persistent Storage (e.g. Local Storage or Session Storage) and later set the sessions using apiSetAns() function
Example:
r.apiAuth(username, password, rIdx => {
console.log("Authenticating CloudCoin on Raida " + rIdx)
}).then(response => {
if (response.status == "done") {
console.log("Auth successfull")
}
})
Input:
{
// Username
username: string,
// Password
password: string
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
// Array of 25 ans
ans: []
}
apiSetAns
The program must set ANs everytime the RaidaMailJS object is re-created. The function is sychronous
Example:
r.apiSetAns(ans)
Input:
{
// Array of sessions
ans: []
}
Output:
```js
{
// Done
status: string
}
apiResolveUsername
Receives the user's ID from a username. The function accepts a string that can contain a few charaters and return all the usernames that begin from this prefix. E.g. if you pass 'Al' as a username and there are three users in the database 'Alice', 'Alexander' and 'Bob' the function will return 'Alice' and 'Alexander' If you need the exact match set 'exact = true'
Example:
let params = {
username: 'Alice',
exact: true
}
r.apiResolveUsername(params).then(response => {
console.log(response)
})
Input:
{
// FQDN, e.g. my.skywallet.cc
username: string,
// Whether to do exact match. Default is false
exact: boolean,
}
Output:
{
// Return code
code: integer,
// Array of Usernames
usernames: []
}
// Username Object
{
// User ID (SN)
id: integer,
// Username
username: string
}
apiFix
The function fixes a CloudCoin. Email is required to generate proper Authenticity Numbers
Example:
r.apiFix(data, (rIdx, state) => {
console.log("Doing job. State " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// CloudCoin to Fix
cc: object,
// Recovery Email
email: string,
// User's Password
password: string
}
Output:
{
// Done
status: string,
// Message
message: string
}
apiRegisterAccount
The function registers a new Account. It generates ANs from username and password. The function also hashes the email and stores it on the RAIDA
Example:
r.apiRegisterAccount(username, email, password, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
// Username
username: string,
// Recovery Email
email: string,
// User's Password
password: string
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
// Generated ANs
ans: []
}
apiUpdateAuth
The function updates account info on RAIDA servers that miss it for some reasno. An array of RAIDA servers need to be passed to the function. The function generates ANs from username and password. The function also hashes the email and stores it on the RAIDA.
Example:
r.apiUpdateAuth(username, email, password, [3, 8], (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
// Username
username: string,
// Recovery Email
email: string,
// User's Password
password: string,
// User's ID
userid: string,
// Array of RAIDA servers
raidas: array
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
// Number of successfully updated raida servers
updated: integer
}
apiUpdateUsername
The function updates user's name
Example:
r.apiUpdateUsername(username, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
// New Username
username: string,
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
}
apiGroupCreate
Creates a new Group. A group can be either 'circle' or 'friend'. If the 'isdialogue' parameter is true then the group is a circle. Otherwise it is a friend.
Example:
r.apiGroupCreate(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// if true then the group is a circle, if false the group is a friend
isdialogue: boolean,
// Username a friend's address. Can't be empty if the group is a friend
username : string,
// Can't be empty if the group is a circle
data : {
// Circle name
name : string,
// Circle picture (url or base64 data) E.g. 'https://my.com/pic.jpg' or 'data:image/png;base64,iVBORw0K'
avatar: string
}
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
// ID of a new group
group_id: string
}
apiSendInvite
Sends an invitation message to the user. The function creates a group and adds the user to this group. If an existing group_id is provided then the group will not be created and the user will be added to the existing group.
Example:
r.apiSendInvite(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// User's email address
email : string,
// Group_ID (optional)
group_id: string
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
}
apiForgotPassword
Sends a 'forgot password' message to the user. The function validates that the user exists and sends 25 emails with a temporary code to his email address
Example:
r.apiForgotPassword(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// User name
username: string,
// User's email address
email : string,
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
}
apiRestorePassword
The function uses codes initially generated by the user when he initiated the password recovery. It accepts an array of 25 codes, username and the new password If some codes are missing then they must not be set. Array length will be smaller in this case. However if there are more than two missing codes the function will reject the request
Example:
r.apiRestorePassword(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// User name
username: string,
// Password
password : string,
// Array of codes
codes: []
}
Output:
{
// Return code
code: integer,
}
apiGroupUpdate
Updates a Group. Only circles can be updated
Example:
r.apiGroupUpdate(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// Group ID
group_id: string,
// Group Data
data : {
// Circle name
name : string,
// Circle picture (url or base64 data) E.g. 'https://my.com/pic.jpg' or 'data:image/png;base64,iVBORw0K'
avatar: string
}
}
Output:
{
// Done
status: string,
}
apiGroupDelete
Deletes a Group. Can be a Friend or a Circle
Example:
r.apiGroupDelete(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// Group ID
group_id: string
}
Output:
{
// Done
status: string,
}
apiGroupList
Lists all groups from the server
Example:
r.apiGroupList({}, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
}
Output:
{
// Return code
code: integer,
// Done
status: string,
// Array of groups
groups: [],
// Failed Sessions Array. See above
failedSessions: [],
// Versions. See above
versions: {}
}
Each group has a structure
```js
{
// if true then the group is a Friend. if false it is a Circle
isdialogue: boolean,
// ID of the group
group_id: string,
// Owner of the group
group_owner: string,
// Number of unread messages
unread_number: number,
// Timestamp of the first unread message
first_unread_time: number,
// Timestamp of the last message in the group
last_message_ts: number,
// User ID
member_sn: string,
// Username (not empty if it is a friend)
username: string,
data: {
// Public avatar (url or base64 data)
avatar: string,
// Name of the group
name: string,
},
// Profile (not empty if user updated it)
profile: {
// Firtname (private)
firstname: string,
// Lastname (private)
lastname: string
// Avatar (private)
avatar: string
}
}
apiGroupMembersList
Lists all members of the group
Example:
r.apiGroupMembersList(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// ID of the group
group_id: string
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
// Array of members
members: []
}
Each group member has a structure
```js
{
// Serial Number
member_sn: string,
// Username
username: string,
// Profile (not empty if user updated it)
data: {
// Firtname (private)
firstname: string,
// Lastname (private)
lastname: string,
// Avatar (private)
avatar: string,
// Member's skywallet
skywallet: string
}
}
apiGroupMembersCreate
Adds members to a Circle
Example:
r.apiGroupMembersCreate(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// ID of the group
group_id: string,
// Members
members: []
}
Each member has a following structure
{
// Serial Number of a member
sn: string
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string
}
apiGroupMembersRemove
Removes members from a Circle
Example:
r.apiGroupMembersRemove(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// ID of the group
group_id: string,
// Members
members: []
}
Each member has a following structure
{
// Serial Number of a member
sn: string
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string
}
apiMessageCreate
Create a message in the group. The message can be either an text message or an attachment. Passing the 'type' parameter specifies the MIME type of the attachment. If the type is missing then the message is a text one.
It is recommended to set higher RAIDAMail timeouts (minute or more) when sending big files
Example:
r.apiMessageCreate(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// ID of the group
group_id: string,
// Message Text
data : string,
// Attachments (optional)
attachments: [
{
// File Name
name : string,
// MIME type of the message. (E.g. image/jpeg or application/octet-stream).
type : string,
// Size in bytes
size: integer,
// File contents base64 encoded
file : string
},
...
]
}
Output:
{
// Done
status: string,
// Message ID
message_id: string
}
apiMessageUpdate
Updates a Message text. Can't be used for attachments
Example:
r.apiMessageUpdate(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// Message ID
message_id: string,
// Message Text
data : string
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
}
apiMessageDelete
Deletes a Message
Example:
r.apiMessageDelete(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// Message ID
message_id: string,
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
}
apiMessagesGet
Gets all messages (without the attachment contents) from RAIDA Mail servers. The messages are not sorted by name or date
Example:
r.apiMessagesGet(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// ID of the group
group_id: string
// Filter. Timestamp (optional)
start_date: string
// Filter. Message ID (optional)
message_id: string
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
// Array of messages
messages: [],
// Failed Sessions Array. See above
failedSessions: [],
// Versions. See above
versions: {}
}
Each message has a structure
```js
{
// ID of the message
message_id: string,
// Message creator SN
author_sn: string,
// Message creator username
author_username: string,
// Timestamp
created: timestamp,
// Message text
data: string,
// Attachments (optional)
attachments: [
{
// ID of the attachment
message_id: string
// Name
name : string,
// Size
size: integer,
// MIME Type
type: string
},
...
]
}
apiMessagesCheck
Checks if new messages are in the group. The caller must pick a random raida server to query.
Example:
r.apiMessagesCheck(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// ID of the group
group_id: string,
// Starting point for looking for the new messages
start_date: timestamp,
// Random Raida Server (from 0 to 24)
rr: number
}
Output:
{
// Done
status: string,
// Array of messages
messages: []
}
Each message has the same structure as in the apiMessagesGet()
apiAttachmentGet
Downloads an attachment
Example:
r.apiAttachmentGet(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// ID of the attachment
message_id: string,
}
Output:
{
// Return code
code: integer,
// Done (Legacy)
status: string,
// Data
attachment: {
// File name
name: string,
// MIME type
type: string,
// Contents (base64 encoded)
msg: string
}
}
apiProfileUpdate
The function Updates user's profile
Example:
r.apiProfileUpdate(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// Serail Number (optional)
sn: string,
// Profile data (private)
data {
// fistname
firstname: string,
// lastname
lastname: string,
// avatar (URL or base64)
avatar: string,
// User's address (e.g. my.skwallet.cc)
skywallet: string
}
}
Output:
{
// Done
status: string,
}
apiProfileGet
Gets user's profile
Example:
r.apiProfileGet({}, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
}
Output:
{
// Done
status: string,
// Data
data: {
// Private
private_data: {
// firstname
firstname: string,
// lastname
lastname: string,
// avatar (URL or base64)
avatar: string,
// User's address (e.g. my.skwallet.cc)
skywallet: string
}
},
// Failed Sessions Array. See above
failedSessions: []
}
apiServicePlansGet
Returns Service Plans on the RAIDA available to subscribe for
Example:
r.apiServicePlansGet({}, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
}
Output:
{
// Done
status: string,
// Code,
code: string
// Data. Array of Service Plans. See below
data: []
// Failed Sessions Array. See above
failedSessions: []
}
Service Plan Object
{
// GUID of the Plan
plan_id: string,
// Plan Name
name: string,
// Description
description: string,
// Whether Attachments are allowed. "0" - not allowed, "1" - allowed
allow_attachments: number,
// Monthly Fee
monthly_price: number,
}
apiSubscriptionGet
Returns the subscription details of the current user
Example:
r.apiSubscriptionGet({}, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
}
Output:
{
// Done
status: string,
// Code,
code: string
// Data. See below
data: {}
// Failed Sessions Array. See above
failedSessions: []
}
Subscription Object
{
// GUID of the Plan
plan_id: string,
// Balance
balance: number,
// Timestamp of the next charge
nextbillts: number
}
apiServicePlanUpgrade
Changes the user's Service Plan. The function charges user's account for a monthly fee of the new service plan. It also ensures that there is enough credits to change the Plan.
Example:
let data = { 'plan_id' : '7336503764020799E47A6A656E0529E7' }
r.apiServicePlanUpgrade(data, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
// ID of the new service Plan
'plan_id' : string
}
Output:
{
// Done
status: string,
// Code,
code: string
// Failed Sessions Array. See above
failedSessions: []
}
apiEcho
Pings RAIDA Servers. The function honors authenticaion
Example:
r.apiEcho({}, (rIdx, state) => {
console.log("Doing job: " + state + ", RaidaIdx " + rIdx)
}).then(response => {
console.log(response)
})
Input:
{
}
Output:
{
// Done
status: string,
// total servers (25)
totalServers: int,
// Array of the last errors seen from RAIDA servers
lastErrors: [],
// Array of results. Each item is a number described below
results: [],
// Array of details. Legacy. (either 'offline' or 'online')
details: []
}
Results Enum:
// RAIDA Server is up and running
RaidaMailJS.ECHO_CODE_ONLINE = 0x1
// RAIDA Server is down
RaidaMailJS.ECHO_CODE_OFFLINE = 0x2
// RAIDA Server is up but authentication fails
RaidaMailJS.ECHO_CODE_AUTH_ERROR = 0x3
// RAIDA Servers returns an error
RaidaMailJS.ECHO_CODE_INTERNAL_ERROR = 0x4