stellar-plus
Version:
beta version of stellar-plus, an all-in-one sdk for the Stellar blockchain
299 lines (298 loc) • 16.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-explicit-any */
const contract_1 = require("@stellar/stellar-sdk/contract");
const soroban_token_1 = require("../../../stellar-plus/asset/soroban-token");
const constants_1 = require("../../../stellar-plus/asset/soroban-token/constants");
const soroban_transaction_1 = require("../../../stellar-plus/core/pipelines/soroban-transaction");
const network_1 = require("../../../stellar-plus/network");
jest.mock('stellar-plus/core/pipelines/soroban-transaction', () => ({
SorobanTransactionPipeline: jest.fn(),
}));
const MOCKED_SOROBAN_TRANSACTION_PIPELINE = soroban_transaction_1.SorobanTransactionPipeline;
const MOCKED_EXECUTE = jest.fn().mockResolvedValue({});
const NETWORK_CONFIG = (0, network_1.TestNet)();
const MOCKED_CONTRACT_ID = 'CBJT4BOMRHYKHZ6HF3QG4YR7Q63BE44G73M4MALDTQ3SQVUZDE7GN35I';
const MOCKED_WASM_HASH = 'eb94566536d7f56c353b4760f6e359eca3631b70d295820fb6de55a796e019ae';
const MOCKED_WASM_FILE = Buffer.from('mockWasm', 'utf-8');
const MOCKED_TX_INVOCATION = {
header: {
source: 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI',
fee: '100',
timeout: 45,
},
signers: [],
};
describe('SorobanToken', () => {
describe('Initialization', () => {
it('should initialize with the contract id', () => {
const token = new soroban_token_1.SorobanTokenHandler({
networkConfig: NETWORK_CONFIG,
contractParameters: {
contractId: MOCKED_CONTRACT_ID,
},
});
expect(token.getContractId()).toBe(MOCKED_CONTRACT_ID);
});
it('should initialize with a custom spec', () => {
const mockedSpec = new contract_1.Spec(['AAAAAAAAAAAAAAAEbmFtZQAAAAAAAAABAAAAEA==']);
const token = new soroban_token_1.SorobanTokenHandler({
networkConfig: NETWORK_CONFIG,
contractParameters: {
contractId: MOCKED_CONTRACT_ID,
spec: mockedSpec,
},
});
const spyTokenSpec = jest.mocked(token.spec);
expect(spyTokenSpec).toBe(mockedSpec);
});
it('should initialize with default spec if nothing no contract parameters are provided', () => {
const token = new soroban_token_1.SorobanTokenHandler({
networkConfig: NETWORK_CONFIG,
});
const spyTokenSpec = jest.mocked(token.spec);
expect(spyTokenSpec).toBe(constants_1.spec);
});
it('should initialize with a custom wasm hash', () => {
const token = new soroban_token_1.SorobanTokenHandler({
networkConfig: NETWORK_CONFIG,
contractParameters: {
wasmHash: MOCKED_WASM_HASH,
},
});
expect(token.getWasmHash()).toBe(MOCKED_WASM_HASH);
});
it('should initialize with a custom wasm', () => {
const token = new soroban_token_1.SorobanTokenHandler({
networkConfig: NETWORK_CONFIG,
contractParameters: {
wasm: MOCKED_WASM_FILE,
},
});
expect(token.getWasm()).toBe(MOCKED_WASM_FILE);
});
});
describe('Core invoke methods', () => {
let token;
let invokeSpy;
beforeEach(() => {
jest.clearAllMocks();
MOCKED_SOROBAN_TRANSACTION_PIPELINE.mockImplementation(() => {
return {
execute: MOCKED_EXECUTE,
};
});
token = new soroban_token_1.SorobanTokenHandler({
networkConfig: NETWORK_CONFIG,
contractParameters: {
contractId: MOCKED_CONTRACT_ID,
},
});
invokeSpy = jest.spyOn(token, 'invokeContract');
});
afterEach(() => {
expect(MOCKED_EXECUTE).toHaveBeenCalledOnce();
});
it('should initialize the contract invoking the initialize method', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const initializeArgs = {
admin: 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI',
decimal: 7,
name: 'mockedName',
symbol: 'mockedSymbol',
};
yield token.initialize(Object.assign(Object.assign({}, initializeArgs), MOCKED_TX_INVOCATION));
expect(invokeSpy).toHaveBeenCalledExactlyOnceWith(Object.assign({ method: constants_1.methods.initialize, methodArgs: Object.assign(Object.assign({}, initializeArgs), { admin: initializeArgs.admin }) }, MOCKED_TX_INVOCATION));
}));
it('should set a new admin', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const currentAdmin = 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI';
const newAdmin = 'GBC7ALQTV35BQ3URS5NUHHSWWN3KEXMRGFJ2S4S6VETJ6QA7QCDA64VI';
const setAdminArgs = {
id: currentAdmin,
new_admin: newAdmin,
};
yield token.setAdmin(Object.assign(Object.assign({}, setAdminArgs), MOCKED_TX_INVOCATION));
expect(invokeSpy).toHaveBeenCalledExactlyOnceWith(Object.assign({ method: constants_1.methods.set_admin, methodArgs: { id: currentAdmin, new_admin: newAdmin } }, MOCKED_TX_INVOCATION));
}));
// TODO: Review the default SPEC file under constants
// It seems it is not fully compliant with CAP46
it.skip('should set an account as authorized', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const accountToAuthorize = 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI';
const setAuthorizedArgs = {
id: accountToAuthorize,
authorize: true,
};
yield token.setAuthorized(Object.assign(Object.assign({}, setAuthorizedArgs), MOCKED_TX_INVOCATION));
expect(invokeSpy).toHaveBeenCalledExactlyOnceWith(Object.assign({ method: constants_1.methods.set_authorized, methodArgs: Object.assign(Object.assign({}, setAuthorizedArgs), { id: accountToAuthorize }) }, MOCKED_TX_INVOCATION));
}));
it('should mint new units', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const recipient = 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI';
const mintArgs = {
to: recipient,
amount: BigInt(125),
};
yield token.mint(Object.assign(Object.assign({}, mintArgs), MOCKED_TX_INVOCATION));
expect(invokeSpy).toHaveBeenCalledExactlyOnceWith(Object.assign({ method: constants_1.methods.mint, methodArgs: Object.assign(Object.assign({}, mintArgs), { to: recipient }) }, MOCKED_TX_INVOCATION));
}));
it('should burn existing units', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const from = 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI';
const burnArgs = {
from,
amount: BigInt(131),
};
yield token.burn(Object.assign(Object.assign({}, burnArgs), MOCKED_TX_INVOCATION));
expect(invokeSpy).toHaveBeenCalledExactlyOnceWith(Object.assign({ method: constants_1.methods.burn, methodArgs: Object.assign(Object.assign({}, burnArgs), { from: from }) }, MOCKED_TX_INVOCATION));
}));
// TODO: Review the default SPEC file under constants
// It seems it is not fully compliant with CAP46
it.skip('should clawback funds from an account', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const targetAccount = 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI';
const clawbackArgs = {
from: targetAccount,
amount: BigInt(510),
};
yield token.clawback(Object.assign(Object.assign({}, clawbackArgs), MOCKED_TX_INVOCATION));
expect(invokeSpy).toHaveBeenCalledExactlyOnceWith(Object.assign({ method: constants_1.methods.clawback, methodArgs: Object.assign(Object.assign({}, clawbackArgs), { from: targetAccount }) }, MOCKED_TX_INVOCATION));
}));
it('should apprve an account as spender', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const from = 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI';
const spender = 'GBC7ALQTV35BQ3URS5NUHHSWWN3KEXMRGFJ2S4S6VETJ6QA7QCDA64VI';
const approveArgs = {
from,
spender,
amount: BigInt(510),
expiration_ledger: 10,
};
yield token.approve(Object.assign(Object.assign({}, approveArgs), MOCKED_TX_INVOCATION));
expect(invokeSpy).toHaveBeenCalledExactlyOnceWith(Object.assign({ method: constants_1.methods.approve, methodArgs: Object.assign(Object.assign({}, approveArgs), { from: from, spender: spender }) }, MOCKED_TX_INVOCATION));
}));
it('should transfer from an account to another', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const from = 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI';
const to = 'GBC7ALQTV35BQ3URS5NUHHSWWN3KEXMRGFJ2S4S6VETJ6QA7QCDA64VI';
const transferArgs = {
from,
to,
amount: BigInt(11),
};
yield token.transfer(Object.assign(Object.assign({}, transferArgs), MOCKED_TX_INVOCATION));
expect(invokeSpy).toHaveBeenCalledExactlyOnceWith(Object.assign({ method: constants_1.methods.transfer, methodArgs: Object.assign(Object.assign({}, transferArgs), { from: from, to: to }) }, MOCKED_TX_INVOCATION));
}));
it('should allow a spender to transfer from an account to another', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const from = 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI';
const to = 'GBC7ALQTV35BQ3URS5NUHHSWWN3KEXMRGFJ2S4S6VETJ6QA7QCDA64VI';
const spender = 'GBDDXMKAGNMZIG6LAVARGB6PHWK2WXBDJDDLD7F4CCTRWZ62BXV7SM2W';
const transferArgs = {
from,
to,
spender,
amount: BigInt(11),
};
yield token.transferFrom(Object.assign(Object.assign({}, transferArgs), MOCKED_TX_INVOCATION));
expect(invokeSpy).toHaveBeenCalledExactlyOnceWith(Object.assign({ method: constants_1.methods.transfer_from, methodArgs: Object.assign(Object.assign({}, transferArgs), { from: from, to: to, spender: spender }) }, MOCKED_TX_INVOCATION));
}));
it('should allow a spender to burn from an account', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const from = 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI';
const spender = 'GBDDXMKAGNMZIG6LAVARGB6PHWK2WXBDJDDLD7F4CCTRWZ62BXV7SM2W';
const burnFromArgs = {
from,
spender,
amount: BigInt(11),
};
yield token.burnFrom(Object.assign(Object.assign({}, burnFromArgs), MOCKED_TX_INVOCATION));
expect(invokeSpy).toHaveBeenCalledExactlyOnceWith(Object.assign({ method: constants_1.methods.burn_from, methodArgs: Object.assign(Object.assign({}, burnFromArgs), { from: from, spender: spender }) }, MOCKED_TX_INVOCATION));
}));
});
describe('Core read from contract methods', () => {
let token;
let readSpy;
beforeEach(() => {
jest.clearAllMocks();
MOCKED_SOROBAN_TRANSACTION_PIPELINE.mockImplementation(() => {
return {
execute: MOCKED_EXECUTE,
};
});
token = new soroban_token_1.SorobanTokenHandler({
networkConfig: NETWORK_CONFIG,
contractParameters: {
contractId: MOCKED_CONTRACT_ID,
},
});
readSpy = jest.spyOn(token, 'readFromContract');
});
afterEach(() => {
expect(MOCKED_EXECUTE).toHaveBeenCalledOnce();
});
it('should read the symbol of the token', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
yield token.symbol(MOCKED_TX_INVOCATION);
expect(readSpy).toHaveBeenCalledExactlyOnceWith({
method: constants_1.methods.symbol,
methodArgs: {},
header: MOCKED_TX_INVOCATION.header,
});
}));
it('should read the name of the token', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
yield token.name(MOCKED_TX_INVOCATION);
expect(readSpy).toHaveBeenCalledExactlyOnceWith({
method: constants_1.methods.name,
methodArgs: {},
header: MOCKED_TX_INVOCATION.header,
});
}));
it('should read the decimals of the token', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
yield token.decimals(MOCKED_TX_INVOCATION);
expect(readSpy).toHaveBeenCalledExactlyOnceWith({
method: constants_1.methods.decimals,
methodArgs: {},
header: MOCKED_TX_INVOCATION.header,
});
}));
// TODO: Review the default SPEC file under constants
// It seems it is not fully compliant with CAP46
it.skip('should read the admin of the token', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
yield token.admin(MOCKED_TX_INVOCATION);
expect(readSpy).toHaveBeenCalledExactlyOnceWith({
method: constants_1.methods.admin,
methodArgs: {},
header: MOCKED_TX_INVOCATION.header,
});
}));
it('should read the balance of an account', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const balanceArgs = {
id: 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI',
};
yield token.balance(Object.assign(Object.assign({}, balanceArgs), MOCKED_TX_INVOCATION));
expect(readSpy).toHaveBeenCalledExactlyOnceWith({
method: constants_1.methods.balance,
methodArgs: { id: balanceArgs.id },
header: MOCKED_TX_INVOCATION.header,
});
}));
// TODO: Review the default SPEC file under constants
// It seems it is not fully compliant with CAP46
it.skip('should read the spendable balance of an account', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const spendableBalanceArgs = {
id: 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI',
};
yield token.spendableBalance(Object.assign(Object.assign({}, spendableBalanceArgs), MOCKED_TX_INVOCATION));
expect(readSpy).toHaveBeenCalledExactlyOnceWith({
method: constants_1.methods.spendable_balance,
methodArgs: { id: spendableBalanceArgs.id },
header: MOCKED_TX_INVOCATION.header,
});
}));
it('should read the allowance for a spender an account', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const allowanceArgs = {
from: 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI',
spender: 'GBDDXMKAGNMZIG6LAVARGB6PHWK2WXBDJDDLD7F4CCTRWZ62BXV7SM2W',
};
yield token.allowance(Object.assign(Object.assign({}, allowanceArgs), MOCKED_TX_INVOCATION));
expect(readSpy).toHaveBeenCalledExactlyOnceWith({
method: constants_1.methods.allowance,
methodArgs: { from: allowanceArgs.from, spender: allowanceArgs.spender },
header: MOCKED_TX_INVOCATION.header,
});
}));
});
});