@akashicpay/sdk
Version:
SDK to interact with the Akashic ecosystem
217 lines • 9.27 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const src_1 = require("../src");
const akashicChain_1 = require("../src/akashicChain");
const currency_1 = require("../src/utils/currency");
const build_sdk_1 = require("./build-sdk");
const mock_1 = require("./mock");
const testOtk = {
key: {
pub: {
pkcs8pem: '0x021c918eac6f6834c5cba98922ed5f266fe1a41779ab2d894cf3d5e4bf088bdb78',
},
prv: {
pkcs8pem: '0x3cd7ac15d137d4ac35d6c1d6a703506a400a9c38b6b6ee20417bbaf1ef86b219',
},
},
name: 'otk',
type: 'secp256k1',
identity: 'AS2d998be3e052d29d1cd2b69f5f7f3532bad011b4698bd97ac8640c888eedd76e',
};
describe('AkashicPay SDK', () => {
const privateKey = testOtk.key.prv.pkcs8pem;
const l2Address = testOtk.identity;
let sdk;
afterEach(() => {
jest.clearAllMocks();
});
describe('Constructor', () => {
it('protects access to OTK in production environment', async () => {
mock_1.mockGet.mockResolvedValueOnce({ status: 200, data: { isBp: true } });
const ap = await src_1.AkashicPay.build({
environment: src_1.Environment.Production,
privateKey,
l2Address,
targetNode: src_1.ACNodes.Singapore1,
});
expect(ap).toBeInstanceOf(src_1.AkashicPay);
});
it('throws error if initializing with non-bp user in production environment', async () => {
mock_1.mockGet.mockResolvedValueOnce({ status: 200, data: { isBp: false } });
await expect(() => src_1.AkashicPay.build({
environment: src_1.Environment.Production,
privateKey,
l2Address,
targetNode: src_1.ACNodes.Singapore1,
})).rejects.toThrow(new src_1.AkashicError(src_1.AkashicErrorCode.IsNotBp));
});
});
describe('Node selection', () => {
it.each([
{ environment: src_1.Environment.Development, nodes: src_1.ACDevNodes },
{ environment: src_1.Environment.Production, nodes: src_1.ACNodes },
])('defaults to fastest $environment node in $environment mode', async ({ environment, nodes }) => {
const healthyStatus = { status: 4 };
const [error, unhealthy, best, ..._rest] = Object.values(nodes);
mock_1.mockGet.mockImplementation(async (url) => {
if (url.includes('is-bp'))
return { status: 200, data: { isBp: true } };
if (url.startsWith(error.node))
return { status: 500, data: 'Internal Server Error' };
if (url.startsWith(unhealthy.node))
return { status: 200, data: { status: 3 } };
if (url.startsWith(best.node)) {
await new Promise((resolve) => setTimeout(resolve, 20));
return { status: 200, data: healthyStatus };
}
await new Promise((resolve) => setTimeout(resolve, 50));
return { status: 200, data: healthyStatus };
});
const sdk = await src_1.AkashicPay.build({
environment,
privateKey,
l2Address,
});
expect(sdk['targetNode']).toBe(best);
});
it('chooses the healthiest node if none have full health', async () => {
mock_1.mockGet.mockImplementation(async (url) => {
if (url.includes('is-bp'))
return { status: 200, data: { isBp: true } };
for (const [i, node] of Object.values(src_1.ACDevNodes).entries()) {
if (!url.startsWith(node.node))
continue;
const status = 3 - i;
await new Promise((resolve) => setTimeout(resolve, 50 * status));
return { status: 200, data: { status } };
}
throw new Error('Unreachable');
});
const sdk = await src_1.AkashicPay.build({
environment: src_1.Environment.Development,
privateKey,
l2Address,
});
expect(sdk['targetNode']).toBe(Object.values(src_1.ACDevNodes)[0]);
});
});
describe('Payout', () => {
beforeEach(async () => {
sdk = await (0, build_sdk_1.buildSDKInstance)({ privateKey, l2Address });
});
const l2Hash = 'ASe5659e1700b9004ef06a622e49b6d367d3a76d3fed5e7872aaf684b51b824a89';
it('Should verify and submit a L1 address', async () => {
jest.spyOn(akashicChain_1.AkashicChain.prototype, 'signPayoutTransaction');
mock_1.mockGet.mockResolvedValueOnce({
data: { l2Address: undefined },
status: 200,
});
const preparedTxn = {
$tx: { $i: { stuff: 'hi' }, $contract: 'xyz', $namespace: 'abc' },
$sigs: { back: 'end' },
};
mock_1.mockPost
.mockResolvedValueOnce({
status: 200,
data: { fromAddress: 'baz', preparedTxn },
})
.mockResolvedValueOnce({
status: 200,
data: { $umid: l2Hash, $summary: { vote: 1, commit: 1 } },
});
expect(await sdk.payout('user123', '0x4838B106FCe9647Bdf1E7877BF73cE8B0BAD5f97', '100', src_1.NetworkSymbol.Ethereum_Mainnet)).toStrictEqual({ l2Hash });
expect(jest.spyOn(akashicChain_1.AkashicChain.prototype, 'signPayoutTransaction')).toHaveBeenCalledWith(preparedTxn, testOtk);
});
it('Should verify and submit a L2 address', async () => {
const l2tx = {
fromAddress: 'fromAddress',
toAddress: 'AStoAddress',
amount: '100',
coinSymbol: src_1.NetworkSymbol.Ethereum_Mainnet,
txToSign: {
$tx: { $i: { stuff: 'hi' }, $contract: 'xyz', $namespace: 'abc' },
$sigs: {},
},
layer: src_1.TransactionLayer.L1,
feesEstimate: '1',
};
const identifier = 'user123';
jest.spyOn(akashicChain_1.AkashicChain.prototype, 'l2Transaction');
mock_1.mockGet.mockResolvedValueOnce({
data: { l2Address: 'l2Address' },
status: 200,
});
mock_1.mockPost.mockResolvedValueOnce({
status: 200,
data: {
$umid: l2Hash,
$summary: {
vote: 1,
commit: 1,
},
},
});
expect(await sdk.payout(identifier, l2tx.toAddress, l2tx.amount, l2tx.coinSymbol)).toStrictEqual({ l2Hash });
expect(jest.spyOn(akashicChain_1.AkashicChain.prototype, 'l2Transaction')).toHaveBeenCalledWith({
otk: testOtk,
amount: (0, currency_1.convertToSmallestUnit)(l2tx.amount, l2tx.coinSymbol),
toAddress: 'l2Address',
coinSymbol: l2tx.coinSymbol,
initiatedToNonL2: l2tx.toAddress,
tokenSymbol: undefined,
identifier,
});
});
});
describe('getDepositAddress', () => {
beforeEach(async () => {
sdk = await (0, build_sdk_1.buildSDKInstance)({ privateKey, l2Address });
});
it('Should create and diffcon a new key', async () => {
const address = 'Foo';
const identifier = 'endUser123';
mock_1.mockGet.mockResolvedValueOnce({
status: 200,
data: {
address: undefined,
},
});
mock_1.mockPost
.mockResolvedValueOnce({
status: 200,
data: {
$umid: '1',
$summary: {
vote: 1,
commit: 1,
},
$responses: [{ id: '1', address, hashes: ['a', 'b'] }],
},
})
.mockResolvedValueOnce({
status: 200,
data: {
$umid: '2',
$summary: {
vote: 1,
commit: 1,
},
$responses: ['confirmed'],
},
});
expect(await sdk.getDepositAddress(src_1.NetworkSymbol.Tron, identifier)).toStrictEqual({ address, identifier });
});
it('Should return existing key', async () => {
const address = 'Foo';
const identifier = 'endUser123';
mock_1.mockGet.mockResolvedValueOnce({
status: 200,
data: {
address,
},
});
expect(await sdk.getDepositAddress(src_1.NetworkSymbol.Tron, identifier)).toStrictEqual({ address, identifier });
});
});
});
//# sourceMappingURL=tests.spec.js.map