sila-sdk
Version:
SDK Access to the Sila API
1,671 lines (1,578 loc) • 150 kB
JavaScript
/* eslint-disable func-names */
import { assert } from 'chai';
import regeneratorRuntime, { async } from 'regenerator-runtime'; // eslint-disable-line no-unused-vars
import uuid4 from 'uuid4';
import moment from 'moment';
import axios from 'axios';
import sinon from 'sinon';
import sila from '../src/index';
const sleep = (ms, description) => {
console.log(`${description} waiting for ${ms / 1000} seconds`);
return new Promise((resolve) => setTimeout(resolve, ms));
};
const generateValidSSN = () => {
const area = Math.ceil(Math.random() * 898);
const group = Math.ceil(Math.random() * 98);
const serial = Math.ceil(Math.random() * 9998);
const areaStr = String(area).padStart(3, '0');
const groupStr = String(group).padStart(2, '0');
const serialStr = String(serial).padStart(4, '0');
return `${areaStr}-${groupStr}-${serialStr}`;
};
sila.configure({
key: '9c17e7b767b8f4a63863caf1619ef3e9967a34b287ce58542f3eb19b5a72f076', // Add your private key here. USE ENV VARIABLE
handle: 'arc_sandbox_test_app01', // Add your app handle here
});
sila.setEnvironment('sandbox');
const invalidWallet = sila.generateWallet();
invalidWallet.privateKey = 'e60a5c57130f4e82782cbdb498943f31fe8f92ab96daac2cc13cbbbf9c0b4d9d';
const wallets = [
sila.generateWallet(),
sila.generateWallet(),
sila.generateWallet(),
sila.generateWallet(),
sila.generateWallet(),
sila.generateWallet(),
sila.generateWallet(),
sila.generateWallet(),
sila.generateWallet(),
];
const firstHandle = `node-sdk-first-handle-${uuid4()}`;
const secondHandle = `node-sdk-second-handle-${uuid4()}`;
const thirdHandle = `node-sdk-third-handle-${uuid4()}`;
const fourthHandle = `node-sdk-fourth-handle-${uuid4()}`;
const fifthHandle = `node-sdk-fifth-handle-${uuid4()}`;
const businessHandle = `node-sdk-biz-handle-${uuid4()}`;
const basicHandle = `node-sdk-basic-handle-${uuid4()}`;
const timestamp = Date.now();
const email = `fake${timestamp}@silamoney.com`;
const fake_card_name = `fake_card_${timestamp}`;
const ckoCardName = `cko_card_${timestamp}`;
const firstUser = new sila.User();
firstUser.firstName = 'First';
firstUser.lastName = 'Last';
firstUser.address = '123 Main St';
firstUser.city = 'Anytown';
firstUser.state = 'NY';
firstUser.zip = '12345';
firstUser.phone = '1234567890';
firstUser.email = `${firstHandle}@silamoney.com`;
firstUser.dateOfBirth = '1990-01-01';
firstUser.ssn = generateValidSSN();
firstUser.cryptoAddress = wallets[0].address;
firstUser.handle = firstHandle;
const secondUser = Object.assign({}, firstUser);
secondUser.firstName = 'Second';
secondUser.email = email;
secondUser.cryptoAddress = wallets[1].address;
secondUser.handle = secondHandle;
const thirdUser = Object.assign({}, firstUser);
thirdUser.firstName = 'Fail';
thirdUser.email = `fail_${thirdHandle}@silamoney.com`;
thirdUser.cryptoAddress = wallets[2].address;
thirdUser.handle = thirdHandle;
const fourthUser = Object.assign({}, firstUser);
fourthUser.firstName = 'Fourth';
fourthUser.email = `${fourthHandle}@silamoney.com`;
fourthUser.cryptoAddress = wallets[4].address;
fourthUser.handle = fourthHandle;
fourthUser.doc_type = 'id_drivers_license';
fourthUser.doc_id = '2397719';
fourthUser.doc_state = 'OR';
const businessUser = Object.assign({}, firstUser);
businessUser.entity_name = 'test business';
businessUser.ssn = undefined;
businessUser.ein = '320567252';
businessUser.email = `${businessHandle}@silamoney.com`;
businessUser.cryptoAddress = wallets[5].address;
businessUser.business_type = 'corporation';
businessUser.business_website = 'https://www.yourbusinesscustomer.com';
businessUser.doing_business_as = 'doing business co';
businessUser.naics_code = 721;
businessUser.registration_state = 'AL';
businessUser.handle = businessHandle;
const basicUser = new sila.User();
basicUser.firstName = 'Basic';
basicUser.lastName = 'User';
basicUser.cryptoAddress = wallets[6].address;
basicUser.handle = basicHandle;
const fifthUser = new sila.User();
fifthUser.firstName = 'Fifth';
fifthUser.lastName = 'User';
fifthUser.cryptoAddress = wallets[7].address;
fifthUser.handle = fifthHandle;
fifthUser.phone = '1234567890';
fifthUser.address = '123 Main St';
fifthUser.city = 'Anytown';
fifthUser.state = 'NY';
fifthUser.zip = '12345';
fifthUser.email = `${fifthHandle}@silamoney.com`;
fifthUser.dateOfBirth = '1990-01-01';
fifthUser.ssn = generateValidSSN();
const plaidToken = () => {
const promise = new Promise((resolve, reject) => {
const requestBody = {
public_key: 'fa9dd19eb40982275785b09760ab79',
initial_products: ['transactions'],
institution_id: 'ins_109508',
credentials: {
username: 'user_good',
password: 'pass_good',
},
};
const options = {
uri: 'https://sandbox.plaid.com/link/item/create',
json: true,
body: requestBody,
};
axios
.post(options.uri, options.body)
.then((response) => {
const body = response.data;
const token = body.public_token;
const accountId = body.accounts[0].account_id;
resolve({ token, accountId });
})
.catch((error) => {
console.error('Error making Plaid API request:', error);
resolve({}); // Resolve with empty object if there's an error
});
});
return promise;
};
const MxProcessorToken = async () => {
const authToken =
'OWNlOTFhZWQtMDA4Zi00YjFmLThlMzktNGU3YTU5NjZlOTVhOmYyZThkYzE4MmY2MzQ5OTk5NjMzMDJlYTE3OGU3NTBkZWU2NDQ3ODM=';
const userGuid = 'USR-78912abf-a65b-4661-806b-bdcf4e062e16';
const memberGuid = 'MBR-1e0d03f3-d42e-46e7-86fb-ae07b79c557a';
const accountGuid = 'ACT-cc129199-606c-41a3-aeec-ee32980362d4';
const scopeString = [
`user-guid:${userGuid}`,
`member-guid:${memberGuid}`,
`account-guid:${accountGuid}`,
].join(' ');
const data = JSON.stringify({
authorization_code: { scope: scopeString },
});
const config = {
method: 'post',
url: 'https://int-api.mx.com/authorization_code',
headers: {
Authorization: `Basic ${authToken}`,
Accept: 'application/vnd.mx.api.v1+json',
'Content-Type': 'application/json',
},
data,
};
const tokenPayload = {};
try {
const response = await axios(config);
const token = response.data.authorization_code.code;
tokenPayload.token = token;
} catch (e) {
tokenPayload.error = JSON.stringify(e);
console.error('Error fetching MX token:', e.message);
}
return tokenPayload;
};
// SANDBOX
const validBusinessUuid = '9f280665-629f-45bf-a694-133c86bffd5e';
const invalidBusinessUuid = '6d933c10-fa89-41ab-b443-2e78a7cc8cac';
const issueTransactionDescriptor = 'Issue Trans';
const transferDescriptor = 'Transfer Trans';
const redeemDescriptor = 'Redeem Trans';
const achRegexString = `${invalidBusinessUuid} could not be found`;
const achRegex = new RegExp(achRegexString);
let eventUuid = '';
const checkHandleTests = [
{
input: firstHandle,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `"${firstHandle}.silamoney.eth" should be available.`,
},
{
input: secondHandle,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `"${secondHandle}.silamoney.eth" should be available.`,
},
{
input: thirdHandle,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `"${thirdHandle}.silamoney.eth" should be available.`,
},
{
input: fourthHandle,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `"${fourthHandle}.silamoney.eth" should be available.`,
},
];
const createEntityTests = [
{
input: firstUser,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `Valid registration test for ${firstHandle}.silamoney.eth`,
},
{
input: secondUser,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `Valid registration test for ${secondHandle}.silamoney.eth`,
},
{
input: thirdUser,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `Valid registration test for ${thirdHandle}.silamoney.eth`,
},
{
input: firstUser,
expectedResult: 'FAILURE',
statusCode: 400,
description: `Invalid registration test for ${firstHandle}.silamoney.eth`,
},
{
input: fourthUser,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `Valid registration test for ${fourthHandle}.silamoney.eth`,
},
{
input: businessUser,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `Valid registration test for ${businessHandle}.silamoney.eth`,
},
{
input: basicUser,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `Valid registration test for ${basicUser.handle}.silamoney.eth`,
},
{
input: fifthUser,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `Valid registration test for ${fifthUser.handle}.silamoney.eth`,
},
];
const checkHandleTakenTests = [
{
input: firstHandle,
expectedResult: 'FAILURE',
statusCode: 200,
description: `"${firstHandle}.silamoney.eth" should be taken.`,
},
{
input: secondHandle,
expectedResult: 'FAILURE',
statusCode: 200,
description: `"${secondHandle}.silamoney.eth" should be taken.`,
},
{
input: thirdHandle,
expectedResult: 'FAILURE',
statusCode: 200,
description: `"${thirdHandle}.silamoney.eth" should be taken.`,
},
{
input: fourthHandle,
expectedResult: 'FAILURE',
statusCode: 200,
description: `"${fourthHandle}.silamoney.eth" should be taken.`,
},
];
const requestKYCTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `"${firstHandle}.silamoney.eth" should be sent for KYC check.`,
},
{
handle: secondHandle,
key: wallets[1].privateKey,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `"${secondHandle}.silamoney.eth" should be sent for KYC check.`,
},
{
handle: fourthHandle,
key: wallets[4].privateKey,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `"${fourthHandle}.silamoney.eth" should be sent for KYC check.`,
},
{
handle: businessHandle,
key: wallets[5].privateKey,
expectedResult: 'SUCCESS',
statusCode: 200,
description: `"${businessHandle}.silamoney.eth" should be sent for KYC check.`,
},
];
const requestKYCLevelTests = [
{
handle: fifthUser.handle,
key: wallets[7].privateKey,
kyc_level: 'KYC-STANDARD',
expectedResult: 'SUCCESS',
statusCode: 200,
description: `${fifthUser.handle} should be sent for KYC-STANDARD check`,
messageRegex: /submitted for KYC review/,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
expectedResult: 'FAILURE',
kyc_level: uuid4(),
statusCode: 403,
messageRegex: /\bKYC flow/,
description: 'Random kyc_level should fail requestKYC',
},
];
const checkKYCTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: 'SUCCESS',
messageRegex: /\bpassed\b/,
description: `"${firstHandle}.silamoney.eth" should pass KYC check.`,
},
{
handle: secondHandle,
key: wallets[1].privateKey,
statusCode: 200,
expectedResult: 'SUCCESS',
messageRegex: /\bpassed\b/,
description: `"${secondHandle}.silamoney.eth" should pass KYC check.`,
},
{
handle: fourthHandle,
key: wallets[4].privateKey,
statusCode: 200,
expectedResult: 'SUCCESS',
messageRegex: /\bpassed\b/,
description: `"${fourthHandle}.silamoney.eth" should pass KYC check.`,
},
{
handle: businessHandle,
key: wallets[5].privateKey,
statusCode: 200,
expectedResult: 'FAILURE',
messageRegex: /\bpassed\b/,
description: `"${businessHandle}.silamoney.eth" should pass KYC check.`,
},
{
handle: fifthHandle,
key: wallets[7].privateKey,
statusCode: 200,
expectedResult: 'SUCCESS',
messageRegex: /\bpassed\b/,
description: `"${fifthHandle}.silamoney.eth" should pass KYC check.`,
},
];
const checkPartnerKYCTests = [
{
query_app_handle: 'digital_geko_e2e_new',
query_user_handle: 'cross_app_check_partner',
statusCode: 200,
expectedResult: 'SUCCESS',
description: `Checking cross app check handle`,
},
];
const accountName1 = `sync_direct_${timestamp}`;
const accountName2 = `defaultpt_${timestamp}`;
const accountName3 = `sync_by_id_${timestamp}`;
const accountName4 = `defaultMx_${timestamp}`;
const linkAccountDirectTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
accountNumber: '123456789012',
routingNumber: '123456780',
accountName: accountName1,
expectedResult: 'SUCCESS',
statusCode: 200,
description: 'Direct bank account link should be successful',
},
{
handle: firstHandle,
key: wallets[0].privateKey,
accountNumber: '123456789013',
routingNumber: '123456780',
accountName: 'delete',
expectedResult: 'SUCCESS',
statusCode: 200,
description: 'Direct bank account link should be successful',
},
{
handle: firstHandle,
key: wallets[0].privateKey,
accountNumber: '123456789013',
routingNumber: '123456780',
accountName: 'forupdate',
expectedResult: 'SUCCESS',
statusCode: 200,
description: 'Direct bank account link should be successful',
},
];
const linkAccountTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
expectedResult: 'SUCCESS',
statusCode: 200,
messageRegex: /successfully linked/,
description: `"${firstHandle}" should link account through plaid token`,
withAccountId: false,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
accountName: accountName2,
expectedResult: 'SUCCESS',
statusCode: 200,
messageRegex: /successfully linked/,
description: `"${firstHandle}" should link account through plaid token`,
withAccountId: false,
plaidTokenType: 'legacy'
},
{
handle: firstHandle,
key: wallets[0].privateKey,
token: `public-sandbox-${uuid4()}`,
expectedResult: 'FAILURE',
statusCode: 400,
messageRegex: /public token is in an invalid format/,
description: 'Random plaid token should fail link account',
withAccountId: false,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
accountName: accountName3,
expectedResult: 'SUCCESS',
statusCode: 200,
messageRegex: /successfully linked/,
description: `"${firstHandle}" should link account with plaid token and account id`,
withAccountId: true,
},
{
handle: secondHandle,
key: wallets[1].privateKey,
expectedResult: 'SUCCESS',
statusCode: 200,
messageRegex: /successfully linked/,
description: `"${secondHandle}" should link account through plaid token`,
withAccountId: false,
},
{
handle: fourthHandle,
key: wallets[4].privateKey,
expectedResult: 'SUCCESS',
statusCode: 200,
messageRegex: /successfully linked/,
description: `"${fourthHandle}" should link account through plaid token`,
withAccountId: false,
},
{
handle: fifthHandle,
key: wallets[7].privateKey,
accountName: 'fifthHandleAccount',
token: 'sandbox',
expectedResult: 'SUCCESS',
statusCode: 200,
messageRegex: /successfully linked/,
description: `"${fifthHandle}" should link account through plaid token`,
},
];
const linkAccountMXTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
accountName: accountName4,
expectedResult: 'SUCCESS',
statusCode: 200,
providerTokenType:'processor',
description: `"${firstHandle}" should link account through MX processor token`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
accountName: 'defaultMxx',
token: 'incorrect-token',
expectedResult: 'FAILURE',
statusCode: 400,
providerTokenType:'processor',
description: `"${firstHandle}" should link account through valid MX processor token`,
},
];
const getAccountsTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
accounts: 6,
description: `"${firstHandle}" should retrieve all accounts`,
},
];
const getAccountBalanceTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
accountName: 'default',
statusCode: 200,
expectedResult: true,
description: `${firstHandle} should retrieve default account balance`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
accountName: accountName1,
statusCode: 400,
expectedResult: false,
description: `${firstHandle} should fail retrieve direct link account balance`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
accountName: accountName4,
statusCode: 200,
expectedResult: true,
description: `${firstHandle} should retrieve default MX account balance`,
},
];
const registerWalletTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
wallet: wallets[3],
nickname: 'new_wallet',
default: true,
statusCode: 200,
expectedResult: true,
description: `${firstHandle} should register new wallet`,
statementsEnabled: true,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
wallet: invalidWallet,
nickname: 'fail_wallet',
default: false,
statusCode: 403,
expectedResult: false,
description: `${firstHandle} should fail register new wallet with invalid signature`,
statementsEnabled: true,
},
];
const secondWalletFilters = new sila.WalletFilters();
secondWalletFilters.blockchain_address = wallets[3].address;
const getWalletsTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
wallets: 2,
description: `${firstHandle} should retrieve all wallets`,
statementsEnabled: true,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
filters: secondWalletFilters,
statusCode: 200,
expectedResult: true,
wallets: 1,
description: `${firstHandle} should retrieve all wallets`,
statementsEnabled: true,
},
];
const updateWalletTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
walletProperties: {
nickname: 'default',
default: true,
},
statusCode: 200,
expectedResult: true,
changes: 2,
description: `${firstHandle} should update wallet successfully`,
blockchainAddress: wallets[0].address,
statementsEnabled: true,
},
{
handle: secondHandle,
key: wallets[1].privateKey,
walletProperties: {
nickname: 'default',
default: true,
},
statusCode: 200,
expectedResult: true,
changes: 2,
description: `${secondHandle} should update wallet successfully`,
blockchainAddress: wallets[1].address,
statementsEnabled: true,
},
];
const getWalletTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
description: `${firstHandle} should retrieve wallet (${wallets[0].address})`,
statusCode: 200,
expectedResult: true,
default: true,
nickname: 'default',
blockchainAddress: wallets[0].address,
statementsEnabled: true,
},
{
handle: firstHandle,
key: wallets[3].privateKey,
description: `${firstHandle} should retrieve wallet (${wallets[3].address})`,
statusCode: 200,
expectedResult: true,
default: false,
nickname: 'new_wallet',
blockchainAddress: wallets[3].address,
statementsEnabled: true,
},
];
const deleteWalletTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 403,
expectedResult: false,
description: `${firstHandle} shouldn't delete default wallet`,
},
{
handle: firstHandle,
key: wallets[3].privateKey,
statusCode: 200,
expectedResult: true,
description: `${firstHandle} should delete wallet`,
},
];
const cancelTransactionTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
generateIssueTransaction: true,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
description: `${firstHandle} should cancel transaction`,
},
];
const issueReferences = [];
const issueSilaTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 50000,
statusCode: 200,
expectedResult: 'SUCCESS',
description: `${firstHandle} should issue sila tokens successfully`,
messageRegex: /submitted to processing queue/,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 50000,
statusCode: 200,
descriptor: issueTransactionDescriptor,
businessUuid: validBusinessUuid,
expectedResult: 'SUCCESS',
description: `${firstHandle} should issue sila tokens successfully with business uuid and descriptor`,
messageRegex: /submitted to processing queue/,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 100,
statusCode: 400,
descriptor: issueTransactionDescriptor,
businessUuid: invalidBusinessUuid,
expectedResult: 'FAILURE',
description: `${firstHandle} should fail issue sila tokens with invalid business uuid and descriptor`,
messageRegex: achRegex,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 100,
statusCode: 200,
processingType: 'SAME_DAY_ACH',
expectedResult: 'SUCCESS',
description: `${firstHandle} should issue sila tokens successfully with processing type`,
messageRegex: /submitted to processing queue/,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 420,
statusCode: 200,
expectedResult: 'SUCCESS',
description: `${firstHandle} should not issue sila tokens`,
},
{
handle: secondHandle,
key: wallets[1].privateKey,
amount: 100,
cardName: fake_card_name,
statusCode: 200,
expectedResult: 'SUCCESS',
description: `${secondHandle} should issue sila tokens successfully with card name`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 200,
accountName: accountName4,
statusCode: 200,
expectedResult: 'SUCCESS',
description: `${fifthHandle} should issue sila tokens successfully with defaultMx`,
},
];
const getTransactionsTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
description: `${firstHandle} should retrieve transactions with user private key signature`,
},
{
handle: firstHandle,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
description: `${firstHandle} should retrieve transactions without user private key signature`,
},
{
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
description: `Should retrieve transactions without user handle and private key signature`,
},
];
const issueTransactionIdempotencyId = uuid4();
const transferTransactionIdempotencyId = uuid4();
const redeemTransactionIdempotencyId = uuid4();
const issueTransactionIdempotencyIdentifier = `issueTransactionIdempotencyIdentifier ${uuid4()}`;
const transferTransactionIdempotencyIdentifier = `transferTransactionIdempotencyIdentifier ${uuid4()}`;
const redeemTransactionIdempotencyIdentifier = `redeemTransactionIdempotencyIdentifier ${uuid4()}`;
const idempotencyIssueReferences = [];
const idempotencySilaTransactionTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 500,
statusCode: 200,
expectedResult: 'SUCCESS',
description: `${firstHandle} should issue sila tokens successfully for Idempotency test`,
messageRegex: /submitted to processing queue/,
transaction_idempotency_id:issueTransactionIdempotencyId,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 500,
statusCode: 200,
expectedResult: 'SUCCESS',
description: `${firstHandle} should issue sila tokens successfully for Idempotency test`,
messageRegex: /submitted to processing queue/,
transaction_idempotency_id:issueTransactionIdempotencyId,
},
];
const idempotencyIdentifierSilaTransactionTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 500,
statusCode: 200,
expectedResult: 'SUCCESS',
description: `${firstHandle} should issue sila tokens successfully for Idempotency Identifier test`,
messageRegex: /submitted to processing queue/,
transaction_idempotency_identifier: issueTransactionIdempotencyIdentifier,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 500,
statusCode: 200,
expectedResult: 'SUCCESS',
description: `${firstHandle} should issue sila tokens successfully for Idempotency Identifier test`,
messageRegex: /submitted to processing queue/,
transaction_idempotency_identifier: issueTransactionIdempotencyIdentifier,
},
];
/**
* Gets and specific index position out of an array
* @param {Number} index The index position in the array
* @param {Array<String>} referencesArray The array of references
*/
const transactionFiltersByRef = (index, referencesArray) => {
const filters = new sila.TransactionFilters();
filters.reference_id = referencesArray[index];
return filters;
};
/**
* Makes a recursive poll to /get_transactions until the transactions finishes.
* Validates the results with the one's expected by the test
* @param {*} test The test object information
* @param {Array<String>} referencesArray The array of references
*/
const pollGetTransactionsTest = async (test, referencesArray) => {
try {
const filters = transactionFiltersByRef(test.filterIndex, referencesArray);
let res = await sila.getTransactions(test.handle, test.key, filters);
let { statusCode } = res;
let { success } = res.data;
let {
status,
error_msg,
error_code,
return_code,
return_desc
} = res.data.transactions[0];
while (
statusCode === 200 &&
success &&
(status === 'pending' || status === 'queued')
) {
/* eslint-disable no-await-in-loop */
await sleep(30000, test.description);
res = await sila.getTransactions(test.handle, test.key, filters);
/* eslint-enable no-await-in-loop */
({ statusCode } = res);
({ success } = res.data);
[{ status, error_msg, error_code, return_code, return_desc }] = res.data.transactions;
}
assert.equal(statusCode, test.statusCode);
assert.equal(success, test.expectedResult);
assert.equal(status, test.status);
if (test.expects_return_code) {
assert.isDefined(error_msg)
assert.isDefined(error_code)
assert.isDefined(return_code)
assert.isDefined(return_desc)
}
} catch (e) {
assert.fail(e);
}
};
const pollIssueTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
filterIndex: 0,
statusCode: 200,
expectedResult: true,
status: 'success',
description: `${firstHandle} should issue sila tokens`,
},
];
const transferReferences = [];
const transferSilaTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: secondHandle,
amount: 100,
description: `${firstHandle} should transfer to ${secondHandle}`,
statusCode: 200,
expectedResult: 'SUCCESS',
},
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: 'digital_geko_e2e.silamoney.eth',
amount: 100,
description: `${firstHandle} should fail transfer to app handle`,
statusCode: 401,
expectedResult: 'FAILURE',
},
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: secondHandle,
amount: 100,
walletNickname: 'default',
description: `${firstHandle} should transfer to ${secondHandle} with wallet nickname`,
statusCode: 200,
expectedResult: 'SUCCESS',
},
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: secondHandle,
amount: 100,
walletNickname: uuid4(),
description: `${firstHandle} should fail transfer to ${secondHandle} with random wallet nickname`,
statusCode: 403,
expectedResult: 'FAILURE',
},
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: secondHandle,
amount: 100,
walletAddress: wallets[1].address,
description: `${firstHandle} should transfer to ${secondHandle} with wallet address`,
statusCode: 200,
expectedResult: 'SUCCESS',
},
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: firstHandle,
amount: 100,
walletAddress: wallets[0].address,
description: `${firstHandle} should fail transfer to ${firstHandle} with the origin wallet address`,
statusCode: 403,
expectedResult: 'FAILURE',
},
{
handle: fourthHandle,
key: wallets[4].privateKey,
destinationHandle: firstHandle,
amount: 100,
description: `${fourthHandle} should fail to init transfer to ${firstHandle}`,
statusCode: 400,
expectedResult: 'FAILURE',
},
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: secondHandle,
amount: 100,
descriptor: transferDescriptor,
businessUuid: validBusinessUuid,
description: `${firstHandle} should transfer to ${secondHandle} with business uuid and descriptor`,
statusCode: 200,
expectedResult: 'SUCCESS',
},
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: secondHandle,
amount: 100,
descriptor: transferDescriptor,
businessUuid: invalidBusinessUuid,
description: `${firstHandle} should fail transfer to ${secondHandle} with invalid business uuid and descriptor`,
statusCode: 400,
expectedResult: 'FAILURE',
},
];
const idempotencyTransferReferences = [];
const transferSilaIdempotencyTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: secondHandle,
amount: 50,
description: `${firstHandle} should transfer to ${secondHandle} for Idempotency test`,
statusCode: 200,
expectedResult: 'SUCCESS',
transaction_idempotency_id: transferTransactionIdempotencyId,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: secondHandle,
amount: 50,
description: `${firstHandle} should transfer to ${secondHandle} for Idempotency test`,
statusCode: 200,
expectedResult: 'SUCCESS',
transaction_idempotency_id: transferTransactionIdempotencyId,
},
];
const transferSilaIdempotencyIdentifierTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: secondHandle,
amount: 50,
description: `${firstHandle} should transfer to ${secondHandle} for Idempotency Identifier test`,
statusCode: 200,
expectedResult: 'SUCCESS',
transaction_idempotency_identifier: transferTransactionIdempotencyIdentifier,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
destinationHandle: secondHandle,
amount: 50,
description: `${firstHandle} should transfer to ${secondHandle} for Idempotency Identifier test`,
statusCode: 200,
expectedResult: 'SUCCESS',
transaction_idempotency_identifier: transferTransactionIdempotencyIdentifier,
},
];
const pollTransferTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
filterIndex: 0,
statusCode: 200,
expectedResult: true,
status: 'success',
description: `${firstHandle} should transfer sila tokens`,
},
];
const getSilaBalanceTests = [
{
address: wallets[1].address,
description: `${wallets[1].address} should have at least 100 tokens in balance`,
statusCode: 200,
expectedResult: true,
balance: 100,
},
];
const openVirtualAccountTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
virtual_account_name: 'testVarAccount-1',
statusCode: 200,
expectedResult: 'SUCCESS',
status: 'success',
virtual_account_id:'',
description: `${firstHandle} should open first virtual account successfully`,
statementsEnabled: false,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
virtual_account_name: 'testVarAccount-2',
statusCode: 200,
expectedResult: 'SUCCESS',
status: 'success',
virtual_account_id:'',
description: `${firstHandle} should open second virtual account successfully`,
statementsEnabled: false,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
virtual_account_name: 'testVarAccount-3',
statusCode: 200,
expectedResult: 'SUCCESS',
status: 'success',
virtual_account_id:'',
description: `${firstHandle} should open third virtual account successfully`,
statementsEnabled: true,
},
];
const paymentMethodsIds = {
'bank_account_id':'',
'card_id':'',
'virtual_account_id_1':'',
'virtual_account_number_1':'',
'virtual_account_id_2':'',
'virtual_account_number_2':'',
'blockchain_address_id':''
}
const redeemReferences = [];
const redeemSilaTests = [
{
handle: secondHandle,
key: wallets[1].privateKey,
amount: 100,
description: `${secondHandle} should redeem sila`,
statusCode: 200,
expectedResult: 'SUCCESS',
},
{
handle: fourthHandle,
key: wallets[4].privateKey,
amount: 100,
description: `${fourthHandle} should fail to init redeem sila`,
statusCode: 400,
expectedResult: 'FAILURE',
},
{
handle: secondHandle,
key: wallets[1].privateKey,
amount: 100,
descriptor: redeemDescriptor,
businessUuid: validBusinessUuid,
description: `${secondHandle} should redeem sila with business uuid and descriptor`,
statusCode: 200,
expectedResult: 'SUCCESS',
},
{
handle: secondHandle,
key: wallets[1].privateKey,
amount: 100,
descriptor: redeemDescriptor,
businessUuid: invalidBusinessUuid,
description: `${secondHandle} should fail redeem sila with invalid business uuid and descriptors`,
statusCode: 400,
expectedResult: 'FAILURE',
},
{
handle: firstHandle,
key: wallets[0].privateKey,
amount: 100,
processingType: 'SAME_DAY_ACH',
description: `${secondHandle} should redeem sila with processing type`,
statusCode: 200,
expectedResult: 'SUCCESS',
},
];
const redeemSilaIdempotencyTests = [
{
handle: secondHandle,
key: wallets[1].privateKey,
amount: 100,
description: `${secondHandle} should redeem sila for Idempotency test`,
statusCode: 200,
expectedResult: 'SUCCESS',
transaction_idempotency_id:redeemTransactionIdempotencyId,
},
{
handle: secondHandle,
key: wallets[1].privateKey,
amount: 100,
description: `${secondHandle} should redeem sila for Idempotency test`,
statusCode: 200,
expectedResult: 'SUCCESS',
transaction_idempotency_id:redeemTransactionIdempotencyId,
},
];
const redeemSilaIdempotencyIdentifierTests = [
{
handle: secondHandle,
key: wallets[1].privateKey,
amount: 100,
description: `${secondHandle} should redeem sila for Idempotency Identifier test`,
statusCode: 200,
expectedResult: 'SUCCESS',
transaction_idempotency_identifier: redeemTransactionIdempotencyIdentifier,
},
{
handle: secondHandle,
key: wallets[1].privateKey,
amount: 100,
description: `${secondHandle} should redeem sila for Idempotency Identifier test`,
statusCode: 200,
expectedResult: 'SUCCESS',
transaction_idempotency_identifier: redeemTransactionIdempotencyIdentifier,
},
];
const pollRedeemTests = [
{
handle: secondHandle,
key: wallets[1].privateKey,
filterIndex: 0,
statusCode: 200,
expectedResult: true,
status: 'success',
description: `${secondHandle} should redeem sila tokens`,
},
];
const plaidSamedayAuthTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
accountName: 'default',
description: `${firstHandle} default account should fail plaid sameday auth`,
statusCode: 400,
expectedResult: 'FAILURE',
},
];
const registrationData = [];
const addEmailTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
email: `added_email_${uuid4()}@gmail.com`,
description: `${firstHandle} should add email`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
email: '',
description: `${firstHandle} should fail to add email`,
},
];
const addPhoneTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
phone: '1234567890',
description: `${secondHandle} should add phone`,
messageRegex: /Successfully added phone/,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
phone: '',
description: `${secondHandle} should fail to add phone`,
messageRegex: /Bad request/,
},
{
handle: fifthUser.handle,
key: wallets[7].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
phone: '1234567891',
description: `${fifthUser.handle} should add phone`,
messageRegex: /Successfully added phone/,
},
];
const addIdentityTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
identity: {
alias: 'SSN',
value: generateValidSSN(),
},
description: `${secondHandle} should add identity`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
identity: {
alias: '',
value: '',
},
description: `${secondHandle} should fail to add identity`,
},
];
const addAddressTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
address: {
alias: 'Home Number Two',
street_address_1: '324 Songbird Avenue',
street_address_2: 'Apt. 132',
city: 'Portland',
state: 'VA',
postal_code: '12345',
country: 'US',
},
description: `${secondHandle} should add address`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
address: {
street_address_2: undefined,
},
description: `${secondHandle} should fail to add address`,
},
];
const updateEmailTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
email: {
email: `${firstHandle}_updated@silamoney.com`,
uuid: 4,
},
description: `${firstHandle} should update email`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
email: {
email: '',
uuid: undefined,
},
description: `${firstHandle} should fail to update email`,
},
];
const updatePhoneTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
phone: {
phone: '1234567890',
uuid: 5,
},
description: `${secondHandle} should update phone`,
messageRegex: /Successfully updated phone/,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
phone: {
phone: '',
uuid: undefined,
},
description: `${secondHandle} should fail to update phone`,
messageRegex: /Bad request/,
},
];
const updateIdentityTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
identity: {
alias: 'SSN',
value: generateValidSSN(),
uuid: 7,
},
description: `${firstHandle} should update identity`,
messageRegex: /Successfully updated identity/,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
identity: {
alias: '',
value: '',
uuid: undefined,
},
description: `${secondHandle} should fail to update identity`,
messageRegex: /Bad request/,
},
];
const updateAddressTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
address: {
alias: 'Home Number Two',
street_address_1: '325 Songbird Avenue',
street_address_2: 'Apt. 132',
city: 'Portlandia',
state: 'WA',
postal_code: '94112',
country: 'US',
uuid: 8,
},
description: `${secondHandle} should update address`,
messageRegex: /Successfully updated address/,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
address: {
alias: '',
street_address_1: '',
street_address_2: '',
city: '',
state: '',
postal_code: '',
country: '',
uuid: undefined,
},
description: `${firstHandle} should fail to update address`,
messageRegex: /Bad request/,
},
];
const updateEntityTests = [
{
handle: firstHandle,
privateKey: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
description: `${firstHandle} should update entity`,
entity: {
first_name: 'NewFirst',
last_name: 'NewLast',
entity_name: 'NewFirst NewLast',
birthdate: '1994-01-08',
},
},
{
handle: businessHandle,
privateKey: wallets[5].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
description: `${businessHandle} should update entity`,
entity: {
entity_name: 'New Company',
business_type: 'corporation',
naics_code: 721,
doing_business_as: 'NC Ltc.',
business_website: 'https://newdomain.go',
registration_state:'OR',
},
},
];
const deleteEmailTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
uuid: 0,
description: `${firstHandle} should delete email`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
uuid: undefined,
description: `${firstHandle} should fail to delete email`,
},
];
const deletePhoneTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
uuid: 1,
description: `${firstHandle} should delete phone`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
uuid: undefined,
description: `${firstHandle} should fail to delete phone`,
},
];
const deleteIdentityTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
uuid: 2,
description: `${firstHandle} should delete identity`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
uuid: undefined,
description: `${firstHandle} should fail to delete identity`,
},
];
const deleteAddressTests = [
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 200,
expectedResult: true,
status: 'SUCCESS',
uuid: 3,
description: `${firstHandle} should delete address`,
},
{
handle: firstHandle,
key: wallets[0].privateKey,
statusCode: 400,
expectedResult: false,
status: 'FAILURE',
uuid: undefined,
description: `${firstHandle} should fail to delete address`,
},
];
const linkBusinessMemberTests = [
{
user_handle: firstHandle,
user_private_key: wallets[0].privateKey,
business_handle: businessHandle,
business_private_key: wallets[5].privateKey,
role: 'administrator',
details: 'first admin',
},
{
user_handle: firstHandle,
user_private_key: wallets[0].privateKey,
business_handle: businessHandle,
business_private_key: wallets[5].privateKey,
role: 'controlling_officer',
details: 'first controlling officer',
},
{
user_handle: firstHandle,
user_private_key: wallets[0].privateKey,
business_handle: businessHandle,
business_private_key: wallets[5].privateKey,
member_handle: secondHandle,
role: 'administrator',
details: 'second admin',
},
{
user_handle: firstHandle,
user_private_key: wallets[0].privateKey,
business_handle: businessHandle,
business_private_key: wallets[5].privateKey,
member_handle: fourthHandle,
role: 'beneficial_owner',
details: 'first beneficial owner',