stellar-plus
Version:
beta version of stellar-plus, an all-in-one sdk for the Stellar blockchain
354 lines (353 loc) • 24.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const stellar_sdk_1 = require("@stellar/stellar-sdk");
const types_1 = require("../../../../stellar-plus/core/types");
const network_1 = require("../../../../stellar-plus/network");
const errors_1 = require("./errors");
const types_2 = require("./types");
const index_1 = require("./index");
const MOCKED_PK_A = 'GACF23GKVFTU77K6W6PWSVN7YBM63UHDULILIEXJO6FR4YKMJ7FW3DTI';
const MOCKED_PK_B = 'GB3MXH633VRECLZRUAR3QCLQJDMXNYNHKZCO6FJEWXVWSUEIS7NU376P';
const MOCKED_PK_C = 'GCPXAF4S5MBXA3DRNBA7XYP55S6F3UN2ZJRAS72BXEJMD7JVMGIGCKNA';
const MOCKED_ACCOUNT_A = new stellar_sdk_1.Account(MOCKED_PK_A, '100');
const TESTNET_PASSPHRASE = (0, network_1.TestNet)().networkPassphrase;
const MOCKED_FEE = '100';
const MOCKED_BUMP_FEE = '101';
const MOCKED_TX_OPTIONS = {
fee: MOCKED_FEE,
networkPassphrase: TESTNET_PASSPHRASE,
timebounds: {
minTime: 0,
maxTime: 0,
},
};
describe('ClassicSignRequirementsPipeline', () => {
describe('Initialization', () => {
it('should initialize pipeline', () => {
const pipeline = new index_1.ClassicSignRequirementsPipeline();
expect(pipeline).toBeDefined();
});
});
describe('errors', () => {
it('should throw error if internal process fails', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const pipeline = new index_1.ClassicSignRequirementsPipeline();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
jest.spyOn(pipeline, 'bundleSignatureRequirements').mockImplementation(() => {
throw new Error('mocked error');
});
const transaction = new stellar_sdk_1.TransactionBuilder(MOCKED_ACCOUNT_A, MOCKED_TX_OPTIONS).build();
const MOCKED_PROCESS_FAILED_ERROR = errors_1.CSRError.processFailed(new Error('mocked error'), {
item: transaction,
meta: {
itemId: 'mocked-id',
beltId: 'mocked-belt-id',
beltType: types_2.ClassicSignRequirementsPipelineType.id,
},
}, transaction);
yield expect(pipeline.execute(transaction)).rejects.toThrow(MOCKED_PROCESS_FAILED_ERROR.message);
yield expect(pipeline.execute(transaction)).rejects.toHaveProperty('code', MOCKED_PROCESS_FAILED_ERROR.code);
}));
});
describe('core requirement calculation', () => {
it('should return signature requirements for an envelope source without operations', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const expectedResult = [{ publicKey: MOCKED_PK_A, thresholdLevel: types_1.SignatureThreshold.medium }];
const pipeline = new index_1.ClassicSignRequirementsPipeline();
const transaction = new stellar_sdk_1.TransactionBuilder(MOCKED_ACCOUNT_A, MOCKED_TX_OPTIONS).build();
yield expect(pipeline.execute(transaction)).resolves.toHaveLength(expectedResult.length);
yield expect(pipeline.execute(transaction)).resolves.toEqual(expect.arrayContaining(expectedResult));
}));
it('should return signature requirements for a fee bump envelope', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const expectedResult = [{ publicKey: MOCKED_PK_B, thresholdLevel: types_1.SignatureThreshold.low }];
const pipeline = new index_1.ClassicSignRequirementsPipeline();
const transaction = new stellar_sdk_1.TransactionBuilder(MOCKED_ACCOUNT_A, MOCKED_TX_OPTIONS).build();
const feeBumpTransaction = stellar_sdk_1.TransactionBuilder.buildFeeBumpTransaction(MOCKED_PK_B, MOCKED_BUMP_FEE, transaction, TESTNET_PASSPHRASE);
yield expect(pipeline.execute(feeBumpTransaction)).resolves.toHaveLength(expectedResult.length);
yield expect(pipeline.execute(feeBumpTransaction)).resolves.toEqual(expect.arrayContaining(expectedResult));
}));
it('should return signature requirements for an envelope source with one operation from same source', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const expectedResult = [{ publicKey: MOCKED_PK_A, thresholdLevel: types_1.SignatureThreshold.medium }];
const pipeline = new index_1.ClassicSignRequirementsPipeline();
const transaction = new stellar_sdk_1.TransactionBuilder(MOCKED_ACCOUNT_A, MOCKED_TX_OPTIONS)
.addOperation(stellar_sdk_1.Operation.payment({ destination: MOCKED_PK_B, asset: stellar_sdk_1.Asset.native(), amount: '10' }))
.build();
yield expect(pipeline.execute(transaction)).resolves.toHaveLength(expectedResult.length);
yield expect(pipeline.execute(transaction)).resolves.toEqual(expect.arrayContaining(expectedResult));
}));
it('should return signature requirements for an envelope source with one operation from different source', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const expectedResult = [
{ publicKey: MOCKED_PK_A, thresholdLevel: types_1.SignatureThreshold.medium },
{ publicKey: MOCKED_PK_C, thresholdLevel: types_1.SignatureThreshold.medium },
];
const pipeline = new index_1.ClassicSignRequirementsPipeline();
const transaction = new stellar_sdk_1.TransactionBuilder(MOCKED_ACCOUNT_A, MOCKED_TX_OPTIONS)
.addOperation(stellar_sdk_1.Operation.payment({ destination: MOCKED_PK_B, asset: stellar_sdk_1.Asset.native(), amount: '10', source: MOCKED_PK_C }))
.build();
yield expect(pipeline.execute(transaction)).resolves.toHaveLength(expectedResult.length);
yield expect(pipeline.execute(transaction)).resolves.toEqual(expect.arrayContaining(expectedResult));
}));
it('should return signature requirements for an envelope source with one operation of higher threshold for same source', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const expectedResult = [{ publicKey: MOCKED_PK_A, thresholdLevel: types_1.SignatureThreshold.high }];
const pipeline = new index_1.ClassicSignRequirementsPipeline();
const transaction = new stellar_sdk_1.TransactionBuilder(MOCKED_ACCOUNT_A, MOCKED_TX_OPTIONS)
.addOperation(stellar_sdk_1.Operation.setOptions({ signer: { ed25519PublicKey: MOCKED_PK_B, weight: 2 } }))
.build();
yield expect(pipeline.execute(transaction)).resolves.toHaveLength(expectedResult.length);
yield expect(pipeline.execute(transaction)).resolves.toEqual(expect.arrayContaining(expectedResult));
}));
it('should return signature requirements for an envelope source with one operation of higher threshold for different source', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const expectedResult = [
{ publicKey: MOCKED_PK_A, thresholdLevel: types_1.SignatureThreshold.medium },
{ publicKey: MOCKED_PK_C, thresholdLevel: types_1.SignatureThreshold.high },
];
const pipeline = new index_1.ClassicSignRequirementsPipeline();
const transaction = new stellar_sdk_1.TransactionBuilder(MOCKED_ACCOUNT_A, MOCKED_TX_OPTIONS)
.addOperation(stellar_sdk_1.Operation.setOptions({ signer: { ed25519PublicKey: MOCKED_PK_B, weight: 2 }, source: MOCKED_PK_C }))
.build();
yield expect(pipeline.execute(transaction)).resolves.toHaveLength(expectedResult.length);
yield expect(pipeline.execute(transaction)).resolves.toEqual(expect.arrayContaining(expectedResult));
}));
});
describe('operations threshold calculation', () => {
let transactionBuilder;
let testOperationRequirement;
const pipeline = new index_1.ClassicSignRequirementsPipeline();
const expectedLow = { publicKey: MOCKED_PK_A, thresholdLevel: types_1.SignatureThreshold.low };
const expectedMedium = { publicKey: MOCKED_PK_A, thresholdLevel: types_1.SignatureThreshold.medium };
const expectedHigh = { publicKey: MOCKED_PK_A, thresholdLevel: types_1.SignatureThreshold.high };
beforeEach(() => {
transactionBuilder = new stellar_sdk_1.TransactionBuilder(MOCKED_ACCOUNT_A, MOCKED_TX_OPTIONS);
testOperationRequirement = (operations, expected) => {
operations.forEach((op) => {
transactionBuilder.addOperation(op);
});
const transaction = transactionBuilder.build();
return pipeline.execute(transaction).then((result) => expect(result).toEqual(expected));
};
});
it('should return threshold medium for createAccount operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.createAccount({ destination: MOCKED_PK_B, startingBalance: '10' });
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for payment operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.payment({ destination: MOCKED_PK_B, asset: stellar_sdk_1.Asset.native(), amount: '10' });
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for pathPaymentStrictSend operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.pathPaymentStrictSend({
sendAsset: stellar_sdk_1.Asset.native(),
destMin: '1',
sendAmount: '10',
destination: MOCKED_PK_B,
destAsset: stellar_sdk_1.Asset.native(),
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for pathPaymentStrictReceive operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.pathPaymentStrictReceive({
sendAsset: stellar_sdk_1.Asset.native(),
sendMax: '10',
destAmount: '1',
destination: MOCKED_PK_B,
destAsset: stellar_sdk_1.Asset.native(),
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for manageSellOffer operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.manageSellOffer({
selling: stellar_sdk_1.Asset.native(),
buying: new stellar_sdk_1.Asset('USD', MOCKED_PK_B),
amount: '10',
price: '1',
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for manageBuyOffer operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.manageBuyOffer({
selling: stellar_sdk_1.Asset.native(),
buying: new stellar_sdk_1.Asset('USD', MOCKED_PK_B),
buyAmount: '10',
price: '1',
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for createPassiveSellOffer operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.createPassiveSellOffer({
selling: stellar_sdk_1.Asset.native(),
buying: new stellar_sdk_1.Asset('USD', MOCKED_PK_B),
amount: '10',
price: '1',
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold high for setOptions operation with signer', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.setOptions({ signer: { ed25519PublicKey: MOCKED_PK_B, weight: 1 } });
yield testOperationRequirement([operation], [expectedHigh]);
}));
it('should return threshold high for setOptions operation with masterWeight', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.setOptions({ masterWeight: 1 });
yield testOperationRequirement([operation], [expectedHigh]);
}));
it('should return threshold high for setOptions operation with lowThreshold', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.setOptions({ lowThreshold: 1 });
yield testOperationRequirement([operation], [expectedHigh]);
}));
it('should return threshold high for setOptions operation with medThreshold', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.setOptions({ medThreshold: 1 });
yield testOperationRequirement([operation], [expectedHigh]);
}));
it('should return threshold high for setOptions operation with highThreshold', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.setOptions({ highThreshold: 1 });
yield testOperationRequirement([operation], [expectedHigh]);
}));
it('should return threshold medium for setOptions operation without any threshold', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const emptySetOptionsOperation = stellar_sdk_1.Operation.setOptions({});
const homeDomainSetOptionsOperation = stellar_sdk_1.Operation.setOptions({ homeDomain: 'example.com' });
const setFlagsSetOptionsOperation = stellar_sdk_1.Operation.setOptions({ setFlags: 1 });
const clearFlagsSetOptionsOperation = stellar_sdk_1.Operation.setOptions({ clearFlags: 1 });
const inflationDestinationSetOptionsOperation = stellar_sdk_1.Operation.setOptions({ inflationDest: MOCKED_PK_B });
yield testOperationRequirement([emptySetOptionsOperation], [expectedMedium]);
yield testOperationRequirement([homeDomainSetOptionsOperation], [expectedMedium]);
yield testOperationRequirement([setFlagsSetOptionsOperation], [expectedMedium]);
yield testOperationRequirement([clearFlagsSetOptionsOperation], [expectedMedium]);
yield testOperationRequirement([inflationDestinationSetOptionsOperation], [expectedMedium]);
}));
it('should return threshold medium changeTrust operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.changeTrust({ asset: stellar_sdk_1.Asset.native() });
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold low allowTrust operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
// If the source of the envelope was the same account as the one allowing the trust
// the threshold would be medium due to the envelope requirement.
// To properly test the low threshold requirement, we need to use a different account as the source.
const operation = stellar_sdk_1.Operation.allowTrust({
source: MOCKED_PK_C,
trustor: MOCKED_PK_B,
assetCode: stellar_sdk_1.Asset.native().code,
authorize: true,
});
yield testOperationRequirement([operation], [expectedMedium, Object.assign(Object.assign({}, expectedLow), { publicKey: MOCKED_PK_C })]);
}));
it('should return threshold high for accountMerge operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.accountMerge({ destination: MOCKED_PK_B });
yield testOperationRequirement([operation], [expectedHigh]);
}));
it('should return threshold medium for manageData operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.manageData({
name: 'key',
value: Buffer.from('value'),
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold low for bumpSequence operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
// If the source of the envelope was the same account as the one allowing the trust
// the threshold would be medium due to the envelope requirement.
// To properly test the low threshold requirement, we need to use a different account as the source.
const operation = stellar_sdk_1.Operation.bumpSequence({ bumpTo: '1', source: MOCKED_PK_C });
yield testOperationRequirement([operation], [expectedMedium, Object.assign(Object.assign({}, expectedLow), { publicKey: MOCKED_PK_C })]);
}));
it('should return threshold medium for createClaimableBalance operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.createClaimableBalance({
asset: stellar_sdk_1.Asset.native(),
amount: '10',
claimants: [new stellar_sdk_1.Claimant(MOCKED_PK_B)],
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for claimClaimableBalance operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.claimClaimableBalance({
balanceId: '000000007a10d2aa862a610c88bdb1aacf3abf54160b09bec9adc62cfe4e0431e6b8b4c3',
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for beginSponsoringFutureReserves operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.beginSponsoringFutureReserves({ sponsoredId: MOCKED_PK_B });
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for endSponsoringFutureReserves operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.endSponsoringFutureReserves({ source: MOCKED_PK_A });
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for revokeSponsorship operation variations', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const revokeAccountOperation = stellar_sdk_1.Operation.revokeAccountSponsorship({ source: MOCKED_PK_C, account: MOCKED_PK_B });
const revokeTrustlineOperation = stellar_sdk_1.Operation.revokeTrustlineSponsorship({
source: MOCKED_PK_C,
account: MOCKED_PK_B,
asset: stellar_sdk_1.Asset.native(),
});
const revokeOfferOperation = stellar_sdk_1.Operation.revokeOfferSponsorship({
source: MOCKED_PK_C,
seller: MOCKED_PK_B,
offerId: '1',
});
const revokeDataOperation = stellar_sdk_1.Operation.revokeDataSponsorship({
source: MOCKED_PK_C,
account: MOCKED_PK_B,
name: 'key',
});
const revokeClaimableBalanceOperation = stellar_sdk_1.Operation.revokeClaimableBalanceSponsorship({
source: MOCKED_PK_C,
balanceId: '000000007a10d2aa862a610c88bdb1aacf3abf54160b09bec9adc62cfe4e0431e6b8b4c3',
});
const revokeLiquidityPoolOperation = stellar_sdk_1.Operation.revokeLiquidityPoolSponsorship({
source: MOCKED_PK_C,
liquidityPoolId: '076bbb9f17f8d47209515a345420d40ea1ebcd3cb6a370ea0d56fc12dbf084cb',
});
const revokeSignerOperation = stellar_sdk_1.Operation.revokeSignerSponsorship({
source: MOCKED_PK_C,
account: MOCKED_PK_B,
signer: { ed25519PublicKey: MOCKED_PK_B },
});
yield testOperationRequirement([revokeAccountOperation], [expectedMedium, Object.assign(Object.assign({}, expectedMedium), { publicKey: MOCKED_PK_C })]);
yield testOperationRequirement([revokeTrustlineOperation], [expectedMedium, Object.assign(Object.assign({}, expectedMedium), { publicKey: MOCKED_PK_C })]);
yield testOperationRequirement([revokeOfferOperation], [expectedMedium, Object.assign(Object.assign({}, expectedMedium), { publicKey: MOCKED_PK_C })]);
yield testOperationRequirement([revokeDataOperation], [expectedMedium, Object.assign(Object.assign({}, expectedMedium), { publicKey: MOCKED_PK_C })]);
yield testOperationRequirement([revokeClaimableBalanceOperation], [expectedMedium, Object.assign(Object.assign({}, expectedMedium), { publicKey: MOCKED_PK_C })]);
yield testOperationRequirement([revokeLiquidityPoolOperation], [expectedMedium, Object.assign(Object.assign({}, expectedMedium), { publicKey: MOCKED_PK_C })]);
yield testOperationRequirement([revokeSignerOperation], [expectedMedium, Object.assign(Object.assign({}, expectedMedium), { publicKey: MOCKED_PK_C })]);
}));
it('should return threshold medium for clawback operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.clawback({ from: MOCKED_PK_B, amount: '10', asset: stellar_sdk_1.Asset.native() });
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for clawbackClaimableBalance operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.clawbackClaimableBalance({
balanceId: '000000007a10d2aa862a610c88bdb1aacf3abf54160b09bec9adc62cfe4e0431e6b8b4c3',
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold low for setTrustLineFlags operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
// If the source of the envelope was the same account as the one allowing the trust
// the threshold would be medium due to the envelope requirement.
// To properly test the low threshold requirement, we need to use a different account as the source.
const operation = stellar_sdk_1.Operation.setTrustLineFlags({
asset: stellar_sdk_1.Asset.native(),
source: MOCKED_PK_C,
trustor: MOCKED_PK_B,
flags: {
authorized: true,
},
});
yield testOperationRequirement([operation], [expectedMedium, Object.assign(Object.assign({}, expectedLow), { publicKey: MOCKED_PK_C })]);
}));
it('should return threshold medium for liquidityPoolDeposit operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.liquidityPoolDeposit({
maxAmountA: '10',
maxAmountB: '10',
minPrice: 1,
maxPrice: 1,
liquidityPoolId: '076bbb9f17f8d47209515a345420d40ea1ebcd3cb6a370ea0d56fc12dbf084cb',
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
it('should return threshold medium for liquidityPoolWithdraw operation', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const operation = stellar_sdk_1.Operation.liquidityPoolWithdraw({
minAmountA: '10',
minAmountB: '10',
amount: '10',
liquidityPoolId: '076bbb9f17f8d47209515a345420d40ea1ebcd3cb6a370ea0d56fc12dbf084cb',
});
yield testOperationRequirement([operation], [expectedMedium]);
}));
});
});