UNPKG

stellar-plus

Version:

beta version of stellar-plus, an all-in-one sdk for the Stellar blockchain

299 lines (298 loc) 16.4 kB
"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, }); })); }); });