diff --git a/lib/order/__tests__/DestroyAsset.js b/lib/order/__tests__/DestroyAsset.js new file mode 100644 index 00000000..0be51cef --- /dev/null +++ b/lib/order/__tests__/DestroyAsset.js @@ -0,0 +1,35 @@ +const algosdk = require('algosdk'); +const ALGOD_SERVER = 'https://node.testnet.algoexplorerapi.io'; +const ALGOD_TOKEN = ''; // { 'X-API-Key': 'VELyABA1dGqGbAVktbew4oACvp0c0298gMgYtYIb' } +const ALGOD_PORT = ''; + +const client = new algosdk.Algodv2( + ALGOD_TOKEN, + ALGOD_SERVER, + ALGOD_PORT, +); +/** + * + * @param {object} assetCreator + * @param {string} assetId + * @return {Promise} + */ +async function destroyAsset(assetCreator, assetId) { + const params = await client.getTransactionParams().do(); + + const dtxn = algosdk.makeAssetDestroyTxnWithSuggestedParams( + assetCreator.addr, + undefined, + assetId, + params); + + const rawSignedTxn = dtxn.signTxn(assetCreator.sk); + const txn = (await client.sendRawTransaction(rawSignedTxn).do()); + const confirmedTxn = await algosdk.waitForConfirmation(client, txn.txId, 4); + console.log(confirmedTxn); + + console.log('asset destroyed'); +} + +module.exports = destroyAsset; + diff --git a/lib/order/__tests__/GenerateAsset.js b/lib/order/__tests__/GenerateAsset.js new file mode 100644 index 00000000..b26758ca --- /dev/null +++ b/lib/order/__tests__/GenerateAsset.js @@ -0,0 +1,60 @@ +const algosdk = require('algosdk'); +const ALGOD_SERVER = 'https://node.testnet.algoexplorerapi.io'; +const ALGOD_TOKEN = ''; // { 'X-API-Key': 'VELyABA1dGqGbAVktbew4oACvp0c0298gMgYtYIb' } +const ALGOD_PORT = ''; + +const client = new algosdk.Algodv2( + ALGOD_TOKEN, + ALGOD_SERVER, + ALGOD_PORT, +); +/** + * + * @param {number} length + * @return {String} + */ +function makeid(length) { + let result = ''; + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + const charactersLength = characters.length; + for ( let i = 0; i < length; i++ ) { + result += characters.charAt(Math.floor(Math.random() * + charactersLength)); + } + return result; +} +/** + * + * @param {object} assetCreator + * @param {number} decimals + * @return {Promise} + */ +async function generateAsset(assetCreator, decimals=6) { + const params = await client.getTransactionParams().do(); + + const createAssetTxn = algosdk.makeAssetCreateTxnWithSuggestedParams( + assetCreator.addr, + undefined, // no note for time being + 10000000, // hardCoded issuance for time being + decimals, // hardCoded decimals for time + false, + assetCreator.addr, + undefined, + assetCreator.addr, + assetCreator.addr, + makeid(7), + makeid(7), + undefined, + undefined, + params); + + const rawSignedTxn = createAssetTxn.signTxn(assetCreator.sk); + const txn = (await client.sendRawTransaction(rawSignedTxn).do()); + const ptx = await algosdk.waitForConfirmation(client, txn.txId, 4); + const assetId = ptx['asset-index']; + + return assetId; +} + +module.exports = generateAsset; + diff --git a/lib/order/__tests__/GenerateTransactionTypes.js b/lib/order/__tests__/GenerateTransactionTypes.js new file mode 100644 index 00000000..f214db97 --- /dev/null +++ b/lib/order/__tests__/GenerateTransactionTypes.js @@ -0,0 +1,151 @@ +const withPlaceAssetTxns = require('../txns/sell/withPlaceAssetTxns'); +const withPlaceAlgoTxns = require('../txns/buy/withPlaceAlgoTxns'); +const withCloseAssetTxns = require('../txns/close/withCloseAssetTxns'); +const withCloseAlgoTxns = require('../txns/close/withCloseAlgoTxns'); +const getTakerOrders = require('../structure/getTakerOrders'); +const {timeout} = require('../../teal/utils'); + +const compile = require('../compile/compile'); +const AlgodexApi = require('../../AlgodexApi'); + +const tesnet = { + config: { + algod: { + uri: 'https://node.testnet.algoexplorerapi.io', + token: '', + }, + indexer: { + uri: 'https://algoindexer.testnet.algoexplorerapi.io', + token: '', + }, + explorer: { + uri: 'https://indexer.testnet.algoexplorerapi.io', + port: '', + }, + dexd: { + uri: 'https://api-testnet-public.algodex.com/algodex-backend', + token: '', + }, + }, +}; + +const algodexApi = new AlgodexApi(tesnet); + +const TransactionGenerator = { + getPlaceASAEscrowOrderTxns: async function(order) { + return await withPlaceAssetTxns( + await compile({ + ...order, + appId: + typeof order.appId === 'undefined' ? + await algodexApi.getAppId(order) : + order.appId, + version: 6, + indexer: algodexApi.indexer, + wallet: { + ...order.wallet, + ...(await algodexApi.http.indexer.fetchAccountInfo(order.wallet)), + }, + }), + ); + }, + getPlaceAlgoEscrowOrderTxns: async function(order) { + return await withPlaceAlgoTxns( + await compile({ + ...order, + appId: + typeof order.appId === 'undefined' ? + await algodexApi.getAppId(order) : + order.appId, + version: 6, + indexer: algodexApi.indexer, + wallet: { + ...order.wallet, + ...(await algodexApi.http.indexer.fetchAccountInfo(order.wallet)), + }, + }), + ); + }, + getCloseASAEscrowOrderTxns: async function(order) { + return await withCloseAssetTxns( + await compile({ + ...order, + appId: + typeof order.appId === 'undefined' ? + await algodexApi.getAppId(order) : + order.appId, + version: 6, + indexer: algodexApi.indexer, + contract: { + creator: order.address, + }, + wallet: { + ...order.wallet, + ...(await algodexApi.http.indexer.fetchAccountInfo(order.wallet)), + }, + }), + ); + }, + getCloseAlgoEscrowOrderTxns: async function(order) { + return await withCloseAlgoTxns( + await compile({ + ...order, + appId: + typeof order.appId === 'undefined' ? + await algodexApi.getAppId(order) : + order.appId, + version: 6, + indexer: algodexApi.indexer, + contract: { + creator: order.address, + }, + wallet: { + ...order.wallet, + ...(await algodexApi.http.indexer.fetchAccountInfo(order.wallet)), + }, + }), + ); + }, + getTakerOrderTxns: async function(order) { + algodexApi.setWallet(order.wallet); + + let _orderbook = await algodexApi.http.dexd.fetchAssetOrders(order.asset.id); + + while ( + Object.values(_orderbook).reduce((a, b) => { + return a.concat(b); // need to put inside the while statement so the expression re runs every time _orderbook changes + }, []).length === 0 + ) { + await timeout(4000); + _orderbook = await algodexApi.http.dexd.fetchAssetOrders( + order.asset.id, + ); + } + + + const orderbook = algodexApi.http.dexd.mapToAllEscrowOrders({ + buy: _orderbook.buyASAOrdersInEscrow, + sell: _orderbook.sellASAOrdersInEscrow, + }); + + return await getTakerOrders(algodexApi, { + ...order, + appId: + typeof order.appId === 'undefined' ? + await algodexApi.getAppId(order) : + order.appId, + version: 6, + indexer: algodexApi.indexer, + asset: { + ...order.asset, + orderbook, + }, + wallet: { + ...order.wallet, + ...(await algodexApi.http.indexer.fetchAccountInfo(order.wallet)), + }, + }); + }, +}; + +module.exports = TransactionGenerator; diff --git a/lib/order/__tests__/Teal.spec.js b/lib/order/__tests__/Teal.spec.js index f0990bc4..1319209d 100644 --- a/lib/order/__tests__/Teal.spec.js +++ b/lib/order/__tests__/Teal.spec.js @@ -7,10 +7,15 @@ */ /* eslint-disable */ -const {test: {getRandomAccount}, transferFunds, closeAccount, deleteApplication} = require('../../teal'); +const { + test: { getRandomAccount }, + transferFunds, + closeAccount, + deleteApplication, +} = require('../../teal'); // const {makePlaceAlgoEscrowOrderTxns} = require('../txns'); -const _beforeAll = require('./beforeAll'); -const _afterAll = require('./afterAll'); +// const _beforeAll = require('./accountSetup'); +// const _afterAll = require('./afterAll'); // const deleteAppTest = require('./teal_tests/deleteAppTest.js'); // const placeOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); // const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); @@ -24,16 +29,16 @@ const JEST_MINUTE_TIMEOUT = 60 * 1000; const config = require('../../teal/test/config'); -describe('ALGO ESCROW ORDER BOOK (opt in test)', () => { +describe.skip('ALGO ESCROW ORDER BOOK (opt in test)', () => { // Create App - beforeAll(async ()=>{ + beforeAll(async () => { if (process.env.TEST_ENV === 'integration') { await _beforeAll(config, 'buy'); } }, JEST_MINUTE_TIMEOUT); // Delete App - afterAll(async ()=>{ + afterAll(async () => { if (process.env.TEST_ENV === 'integration') { await _afterAll(config); } @@ -45,8 +50,8 @@ describe('ALGO ESCROW ORDER BOOK (opt in test)', () => { [config, 800000, 1.375, false, true], // runGroupSizeWrongTest2 [config, 800000, 1.375, false, true], - ].forEach((run)=>{ - it('should say something', ()=>{ + ].forEach((run) => { + it('should say something', () => { expect(2).toEqual(2); }); }); diff --git a/lib/order/__tests__/TealAlgoEscrowCancel.spec.js b/lib/order/__tests__/TealAlgoEscrowCancel.spec.js index 077828ed..5de48e94 100644 --- a/lib/order/__tests__/TealAlgoEscrowCancel.spec.js +++ b/lib/order/__tests__/TealAlgoEscrowCancel.spec.js @@ -5,106 +5,63 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +const config = require('./TealConfig'); +const {timeout} = require('../../../lib/teal/utils'); +const placeAlgoOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); +const closeAlgoOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); +const JEST_MINUTE_TIMEOUT = 60 * 1000; +const accountSetup = require('./accountSetup.js'); +const accountCleanup = require('./accountCleanup'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset'); -/* eslint-disable max-len */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); + +describe(`ALGO ESCROW CANCEL`, () => { + const price = 1.2; + const amount = 0.8; + + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + + const note = ` + Testing: TealAlgoEscrowCancel + assetId: ${assetId} + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + + Creator Account is buying ${amount} LAMPC at price: ${price} Algo + `; + config.assetId = assetId; + + await accountSetup(config, 'buy', true, false, note); + await timeout(7000); // Eliminates race condition where future indexer calls occur before setUp step fully propogates but after it succeeds + }, JEST_MINUTE_TIMEOUT); + + afterAll(async () => { + await timeout(4000); + await accountCleanup(config, 'buy', true); + await destroyAsset(config.openAccount, config.assetId); + }, JEST_MINUTE_TIMEOUT); + + + test( + 'Place Algo Escrow Order', + async () => { + const result = await placeAlgoOrderTest.runTest(config, amount, price); + expect(result).toBeTruthy(); + + await timeout(7000); + }, + JEST_MINUTE_TIMEOUT * 10, + ); + + test( + 'Close Algo escrow order', + async () => { + const result = await closeAlgoOrderTest.runTest(config, price, amount); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT * 2, + ); }); -// const testHelper = require('./setup.js'); -// const transactionGenerator = require('../generate_transaction_types.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const placeOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const executeAsaOrderTest = require('./teal_tests/executeASAEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const algosdk = require('algosdk'); -// -// -// const AlgodexApi = require('../algodex_api.js'); -// const constants = require('../constants.js'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// const negativeTests = [ -// {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 0, field: 'appIndex', val: 888}, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 0, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount, -// }, -// }, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 1, field: 'amount', val: 10}, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, field: 'amount', val: 10}, -// {txnNum: 2, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// ]; -// -// describe('ALGO ESCROW ORDER BOOK (opt in test)', () => { -// test('Create algo escrow order book', async () => { -// config.appId = await createAppTest.runTest(config, true); -// global.ALGO_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// config.oldCreatorAccount = config.creatorAccount; -// // make a new creatorAccount that hasn't been opted into any ASA -// config.creatorAccount = testHelper.getRandomAccount(); -// -// testHelper.transferFunds(config.client, config.openAccount, config.creatorAccount, 2000000); -// testHelper.transferFunds(config.client, config.openAccount, config.maliciousAccount, 2000000); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Place algo escrow order', async () => { -// let asaBalance = await testHelper.getAssetBalance(config.creatorAccount.addr, config.assetId); -// expect(asaBalance).toBeNull(); -// -// const result = await placeOrderTest.runTest(config, 800000, 1.2); -// expect(result).toBeTruthy(); -// -// asaBalance = await testHelper.getAssetBalance(config.creatorAccount.addr, config.assetId); -// expect(asaBalance).toEqual(0); -// }, JEST_MINUTE_TIMEOUT); -// -// negativeTests.map( (negTestTxnConfig) => { -// const testName = `Negative cancel order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await closeOrderTest.runTest(config, 1.2, true); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// test('Close algo escrow order', async () => { -// const result = await closeOrderTest.runTest(config, 1.2); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Delete algo escrow order book', async () => { -// await testHelper.closeAccount(config.client, config.creatorAccount, config.openAccount); -// config.creatorAccount = config.oldCreatorAccount; -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// diff --git a/lib/order/__tests__/TealAlgoEscrowPayCloseout.spec.js b/lib/order/__tests__/TealAlgoEscrowPayCloseout.spec.js index d7d7e8d3..8a7d3c9c 100644 --- a/lib/order/__tests__/TealAlgoEscrowPayCloseout.spec.js +++ b/lib/order/__tests__/TealAlgoEscrowPayCloseout.spec.js @@ -6,116 +6,82 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); -}); -// const testHelper = require('./setup.js'); -// const transactionGenerator = require('../generate_transaction_types.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const placeOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const executeAsaOrderTest = require('./teal_tests/executeASAEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const algosdk = require('algosdk'); -// -// -// const AlgodexApi = require('../algodex_api.js'); -// const constants = require('../constants.js'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// const textEncoder = new TextEncoder(); -// -// const negTests = [ -// {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 0, field: 'appArgs', innerNum: 0, val: textEncoder.encode('execute')}, -// {txnNum: 0, field: 'appIndex', configKeyForVal: 'fakeAppId'}, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 1, negTxn: { -// unsignedTxnPromise: c.getAssetSendTxn(config.client, config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, config.assetId, false), -// senderAcct: config.maliciousAccount, -// }, -// }, -// {txnNum: 2, field: 'from', txnKeyForVal: 'from', txnNumForVal: 1}, // set to from escrow -// {txnNum: 2, field: 'to', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount, -// }, -// }, -// -// ]; -// -// describe('ALGO ESCROW ORDER BOOK (opt in test)', () => { -// test('Create algo escrow order book', async () => { -// config.appId = await createAppTest.runTest(config, true); -// config.fakeAppId = await createAppTest.createFakeApp(config); -// global.ALGO_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// config.oldCreatorAccount = config.creatorAccount; -// // make a new creatorAccount that hasn't been opted into any ASA -// config.creatorAccount = testHelper.getRandomAccount(); -// testHelper.transferFunds(config.client, config.openAccount, config.creatorAccount, 2000000); -// testHelper.transferFunds(config.client, config.openAccount, config.maliciousAccount, 2000000); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Place algo escrow order', async () => { -// let asaBalance = await testHelper.getAssetBalance(config.creatorAccount.addr, config.assetId); -// expect(asaBalance).toBeNull(); -// -// const result = await placeOrderTest.runTest(config, 800000, 1.2); -// expect(result).toBeTruthy(); -// -// asaBalance = await testHelper.getAssetBalance(config.creatorAccount.addr, config.assetId); -// expect(asaBalance).toEqual(0); -// }, JEST_MINUTE_TIMEOUT); -// -// negTests.map( (negTestTxnConfig) => { -// const testName = `Negative algo full execution order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await executeAlgoOrderTest.runFullExecTest(config, true); -// outerTxns.map( (txn) => { -// const unsignedTxn = txn.unsignedTxn; -// // console.log({unsignedTxn}); -// }); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// test('Fully execute algo escrow order', async () => { -// const result = await executeAlgoOrderTest.runFullExecTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Delete algo escrow order book', async () => { -// await testHelper.closeAccount(config.client, config.creatorAccount, config.openAccount); -// config.creatorAccount = config.oldCreatorAccount; -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); +const accountSetup = require('./accountSetup.js'); +const placeAlgoOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); +const {timeout} = require('../../teal/utils'); +const closeAlgoOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); +const executeAlgoEscrowOrderTest = require('./teal_tests/executeAlgoEscrowOrder'); +const JEST_MINUTE_TIMEOUT = 60 * 1000; +const config = require('./TealConfig'); +const takerAccountCleanup = require('./takerAccountCleanup'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset'); + // +describe('Algo ESCROW PAY CLOSEOUT', () => { + const asaAmount = 0.4; + const price = 1.25; + const executorAmount = 0.4; + + + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + + const note = ` + Testing: TealAlgoEscrowPayCloseout + assetId: ${assetId} + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + + Creator Account is buying ${asaAmount} LAMPC at price: ${price} Algo + Executor Account is selling ${executorAmount} LAMPC + `; + config.assetId = assetId; + await accountSetup(config, 'buy', true, true, note); + await timeout(7000); // Eliminates race condition where future indexer calls occur before setUp step fully propogates but after it succeeds + }, JEST_MINUTE_TIMEOUT*3); + + afterAll(async () => { + await timeout(4000); + await takerAccountCleanup(config, 'buy', executorAmount, true); + await destroyAsset(config.openAccount, config.assetId); + }, JEST_MINUTE_TIMEOUT); + + test( + 'Place Algo escrow order', + async () => { + // set up the Algo Escrow to be executed + const result = await placeAlgoOrderTest.runTest(config, asaAmount, price); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Closeout algo escrow order (no opt-in txn)', + async () => { + const result = await executeAlgoEscrowOrderTest.runTest( + config, + executorAmount, + price, + ); + expect(result).toBeTruthy(); + await timeout(4000); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Close algo escrow order', + async () => { + const result = await closeAlgoOrderTest.runTest( + config, + price, + asaAmount - executorAmount, + ); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); +}); diff --git a/lib/order/__tests__/TealAlgoEscrowPayPartial.spec.js b/lib/order/__tests__/TealAlgoEscrowPayPartial.spec.js index b454840b..1494a0c4 100644 --- a/lib/order/__tests__/TealAlgoEscrowPayPartial.spec.js +++ b/lib/order/__tests__/TealAlgoEscrowPayPartial.spec.js @@ -6,123 +6,90 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); -}); -// const testHelper = require('./setup.js'); -// const transactionGenerator = require('../generate_transaction_types.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const placeOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const executeAsaOrderTest = require('./teal_tests/executeASAEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const algosdk = require('algosdk'); -// -// -// const AlgodexApi = require('../algodex_api.js'); -// const constants = require('../constants.js'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// const textEncoder = new TextEncoder(); -// -// // TODO: The negative tests need to be implemented. The commented ones out are examples but will not work with -// // this transaction type. -// const negTests = [ -// /* {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 0, field: 'appArgs', innerNum: 0, val: textEncoder.encode('execute') }, -// {txnNum: 0, field: 'appIndex', configKeyForVal: 'fakeAppId' }, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, negTxn: { -// unsignedTxnPromise: transactionGenerator.getAssetSendTxn(config.client, config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, config.assetId, false), -// senderAcct: config.maliciousAccount -// } -// }, -// {txnNum: 2, field: 'from', txnKeyForVal: 'from', txnNumForVal: 1}, //set to from escrow -// {txnNum: 2, field: 'to', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount -// } -// },*/ -// -// ]; -// -// describe('ALGO ESCROW ORDER BOOK (opt in test)', () => { -// test('Create algo escrow order book', async () => { -// config.appId = await createAppTest.runTest(config, true); -// config.fakeAppId = await createAppTest.createFakeApp(config); -// global.ALGO_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// config.oldCreatorAccount = config.creatorAccount; -// // make a new creatorAccount that hasn't been opted into any ASA -// config.creatorAccount = testHelper.getRandomAccount(); -// testHelper.transferFunds(config.client, config.openAccount, config.creatorAccount, 2000000); -// testHelper.transferFunds(config.client, config.openAccount, config.maliciousAccount, 2000000); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Place algo escrow order', async () => { -// let asaBalance = await testHelper.getAssetBalance(config.creatorAccount.addr, config.assetId); -// expect(asaBalance).toBeNull(); -// -// const result = await placeOrderTest.runTest(config, 800000, 1.2); -// expect(result).toBeTruthy(); -// -// asaBalance = await testHelper.getAssetBalance(config.creatorAccount.addr, config.assetId); -// expect(asaBalance).toEqual(0); -// }, JEST_MINUTE_TIMEOUT); -// -// negTests.map( (negTestTxnConfig) => { -// const testName = `Negative algo full execution order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await executeAlgoOrderTest.runFullExecTest(config, true); -// outerTxns.map( (txn) => { -// const unsignedTxn = txn.unsignedTxn; -// // console.log({unsignedTxn}); -// }); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// test('Partially execute algo escrow order', async () => { -// const result = await executeAlgoOrderTest.runPartialExecTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Close algo escrow order', async () => { -// const result = await closeOrderTest.runTest(config, 1.2); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Delete algo escrow order book', async () => { -// await testHelper.closeAccount(config.client, config.creatorAccount, config.openAccount); -// config.creatorAccount = config.oldCreatorAccount; -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); + +const accountSetup = require('./accountSetup.js'); +const placeAlgoOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); +const {timeout} = require('../../teal/utils'); +const closeAlgoOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); +const executeAlgoEscrowOrderTest = require('./teal_tests/executeAlgoEscrowOrder'); +const JEST_MINUTE_TIMEOUT = 60 * 1000; +const config = require('./TealConfig'); +const takerAccountCleanup = require('./takerAccountCleanup'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset'); + // +describe('Algo ESCROW PAY PARTIAL', () => { + const asaAmount = 0.4; + const price = 1.25; + const executorAmount = 0.2; + + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + + const note = ` + Testing: TealAlgoEscrowPayPartial + assetId: ${assetId} + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + Executor Account: ${config.executorAccount.addr} + + Creator Account is buying ${asaAmount} LAMPC at price: ${price} Algo + Executor Account is selling ${executorAmount} LAMPC + `; + config.assetId = assetId; + + + await accountSetup(config, 'buy', true, true, note); + await timeout(7000); // Eliminates race condition where future indexer calls occur before setUp step fully propogates but after it succeeds + }, JEST_MINUTE_TIMEOUT); + + afterAll(async () => { + await timeout(4000); + await takerAccountCleanup(config, 'buy', executorAmount); + await destroyAsset(config.openAccount, config.assetId); + }, JEST_MINUTE_TIMEOUT); + + test( + 'Place Algo escrow order', + async () => { + // set up the Algo Escrow to be executed + const result = await placeAlgoOrderTest.runTest(config, asaAmount, price); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Partially execute algo escrow order (no opt-in txn)', + async () => { + const result = await executeAlgoEscrowOrderTest.runTest( + config, + executorAmount, + price, + ); + expect(result).toBeTruthy(); + await timeout(4000); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Close algo escrow order', + async () => { + const result = await closeAlgoOrderTest.runTest( + config, + price, + asaAmount - executorAmount, + ); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); + + // test('Delete asa escrow order book', async () => { + // const result = await deleteAppTest.runTest(config); + // expect(result).toBeTruthy(); + // }, JEST_MINUTE_TIMEOUT); +}); diff --git a/lib/order/__tests__/TealAlgoEscrowPlaceNoOptInTxn.spec.js b/lib/order/__tests__/TealAlgoEscrowPlaceNoOptInTxn.spec.js index bcf443b7..11007a90 100644 --- a/lib/order/__tests__/TealAlgoEscrowPlaceNoOptInTxn.spec.js +++ b/lib/order/__tests__/TealAlgoEscrowPlaceNoOptInTxn.spec.js @@ -6,116 +6,62 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -/* eslint-disable max-len */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); +const placeAlgoOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); +const accountSetup = require('./accountSetup.js'); +const JEST_MINUTE_TIMEOUT = 60 * 1000; +const config = require('./TealConfig'); +const {timeout} = require('../../teal/utils'); +const closeAlgoOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); +const accountCleanup = require('./accountCleanup.js'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset'); + +describe('ALGO ESCROW PLACE NO OPT IN TXN', () => { + const amount = 0.8; + const price = 1.2; + + + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + const note = ` + Testing: TealAlgoEscrowPlaceNoOptInTxn + assetId: ${assetId} + + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + + Creator Account is buying ${amount} LAMPC at price: ${price} Algo + `; + config.assetId = assetId; + await accountSetup(config, 'buy', true, false, note); // optIn in the setUp phase to test sdk no optIn + await timeout(7000); // Eliminates race condition where future indexer calls occur before setUp step fully propogates but after it succeeds + }, JEST_MINUTE_TIMEOUT); + + afterAll(async () => { + await timeout(4000); + await accountCleanup(config, 'buy', true); + await destroyAsset(config.openAccount, config.assetId); + }, JEST_MINUTE_TIMEOUT); + + test( + 'Place algo escrow order', + async () => { + const result = await placeAlgoOrderTest.runTest(config, amount, price); + expect(result).toBeTruthy(); + await timeout(4000); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Close algo escrow order', + async () => { + await timeout(3000); + const result = await closeAlgoOrderTest.runTest(config, price, amount); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); }); -// const testHelper = require('./setup.js'); -// const transactionGenerator = require('../generate_transaction_types.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const placeOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const executeAsaOrderTest = require('./teal_tests/executeASAEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const algosdk = require('algosdk'); -// -// -// const AlgodexApi = require('../algodex_api.js'); -// const constants = require('../constants.js'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// const textEncoder = new TextEncoder(); -// -// // TODO: The negative tests need to be implemented. The commented ones out are examples but will not work with -// // this transaction type. -// const negTests = [ -// /* {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 0, field: 'appArgs', innerNum: 0, val: textEncoder.encode('execute') }, -// {txnNum: 0, field: 'appIndex', configKeyForVal: 'fakeAppId' }, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, negTxn: { -// unsignedTxnPromise: transactionGenerator.getAssetSendTxn(config.client, config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, config.assetId, false), -// senderAcct: config.maliciousAccount -// } -// }, -// {txnNum: 2, field: 'from', txnKeyForVal: 'from', txnNumForVal: 1}, //set to from escrow -// {txnNum: 2, field: 'to', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount -// } -// },*/ -// -// ]; -// -// describe('ALGO ESCROW ORDER BOOK (opt in test)', () => { -// test('Create algo escrow order book', async () => { -// config.appId = await createAppTest.runTest(config, true); -// config.fakeAppId = await createAppTest.createFakeApp(config); -// global.ALGO_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// -// testHelper.transferFunds(config.client, config.openAccount, config.creatorAccount, 2000000); -// testHelper.transferFunds(config.client, config.openAccount, config.maliciousAccount, 2000000); -// }, JEST_MINUTE_TIMEOUT); -// -// -// negTests.map( (negTestTxnConfig) => { -// const testName = `Negative algo full execution order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await executeAlgoOrderTest.runFullExecTest(config, true); -// outerTxns.map( (txn) => { -// const unsignedTxn = txn.unsignedTxn; -// // console.log({unsignedTxn}); -// }); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// test('Place algo escrow order', async () => { -// let asaBalance = await testHelper.getAssetBalance(config.creatorAccount.addr, config.assetId); -// expect(asaBalance).toBeGreaterThan(0); // already opted in and has ASA -// -// const result = await placeOrderTest.runTest(config, 800000, 1.2); -// expect(result).toBeTruthy(); -// -// asaBalance = await testHelper.getAssetBalance(config.creatorAccount.addr, config.assetId); -// expect(asaBalance).toBeGreaterThan(0); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Close algo escrow order', async () => { -// const result = await closeOrderTest.runTest(config, 1.2); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Delete algo escrow order book', async () => { -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); // diff --git a/lib/order/__tests__/TealAlgoEscrowPlaceWithOptInTxn.spec.js b/lib/order/__tests__/TealAlgoEscrowPlaceWithOptInTxn.spec.js index dc42257f..b07f490b 100644 --- a/lib/order/__tests__/TealAlgoEscrowPlaceWithOptInTxn.spec.js +++ b/lib/order/__tests__/TealAlgoEscrowPlaceWithOptInTxn.spec.js @@ -6,119 +6,60 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); +const placeAlgoOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); +const accountSetup = require('./accountSetup.js'); +const JEST_MINUTE_TIMEOUT = 60 * 1000; +const config = require('./TealConfig'); +const {timeout} = require('../../teal/utils'); +const closeAlgoOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); +const accountCleanup = require('./accountCleanup.js'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset'); + +describe('ALGO ESCROW PLACE WITH OPT IN TXN', () => { + const amount = 0.8; + const price = 1.2; + + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + + const note = ` + Testing: TealAlgoEscrowPlaceWithOptInTxn + assetId: ${assetId} + + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + + Creator Account is buying ${amount} LAMPC at price: ${price} Algo + `; + config.assetId = assetId; + + await accountSetup(config, 'buy', false, false, note); + await timeout(10000); // Eliminates race condition where future indexer calls occur before setUp step fully propogates but after it succeeds + }, JEST_MINUTE_TIMEOUT); + + afterAll(async () => { + await timeout(4000); + await accountCleanup(config, 'buy', false); + await destroyAsset(config.openAccount, config.assetId); + }, JEST_MINUTE_TIMEOUT); + + test( + 'Place algo escrow order', + async () => { + const result = await placeAlgoOrderTest.runTest(config, amount, price); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Close algo escrow order', + async () => { + const result = await closeAlgoOrderTest.runTest(config, price, amount); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); }); -// const testHelper = require('./setup.js'); -// const transactionGenerator = require('../generate_transaction_types.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const placeOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const executeAsaOrderTest = require('./teal_tests/executeASAEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const algosdk = require('algosdk'); -// -// -// const AlgodexApi = require('../algodex_api.js'); -// const constants = require('../constants.js'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// const textEncoder = new TextEncoder(); -// -// // TODO: The negative tests need to be implemented. The commented ones out are examples but will not work with -// // this transaction type. -// const negTests = [ -// /* {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 0, field: 'appArgs', innerNum: 0, val: textEncoder.encode('execute') }, -// {txnNum: 0, field: 'appIndex', configKeyForVal: 'fakeAppId' }, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, negTxn: { -// unsignedTxnPromise: transactionGenerator.getAssetSendTxn(config.client, config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, config.assetId, false), -// senderAcct: config.maliciousAccount -// } -// }, -// {txnNum: 2, field: 'from', txnKeyForVal: 'from', txnNumForVal: 1}, //set to from escrow -// {txnNum: 2, field: 'to', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount -// } -// },*/ -// -// ]; -// -// describe('ALGO ESCROW ORDER BOOK (opt in test)', () => { -// test('Create algo escrow order book', async () => { -// config.appId = await createAppTest.runTest(config, true); -// config.fakeAppId = await createAppTest.createFakeApp(config); -// global.ALGO_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// config.oldCreatorAccount = config.creatorAccount; -// // make a new creatorAccount that hasn't been opted into any ASA -// config.creatorAccount = testHelper.getRandomAccount(); -// testHelper.transferFunds(config.client, config.openAccount, config.creatorAccount, 2000000); -// testHelper.transferFunds(config.client, config.openAccount, config.maliciousAccount, 2000000); -// }, JEST_MINUTE_TIMEOUT); -// -// -// negTests.map( (negTestTxnConfig) => { -// const testName = `Negative algo full execution order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await executeAlgoOrderTest.runFullExecTest(config, true); -// outerTxns.map( (txn) => { -// const unsignedTxn = txn.unsignedTxn; -// // console.log({unsignedTxn}); -// }); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// test('Place algo escrow order', async () => { -// let asaBalance = await testHelper.getAssetBalance(config.creatorAccount.addr, config.assetId); -// expect(asaBalance).toBeNull(); -// -// const result = await placeOrderTest.runTest(config, 800000, 1.2); -// expect(result).toBeTruthy(); -// -// asaBalance = await testHelper.getAssetBalance(config.creatorAccount.addr, config.assetId); -// expect(asaBalance).toEqual(0); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Close algo escrow order', async () => { -// const result = await closeOrderTest.runTest(config, 1.2); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Delete algo escrow order book', async () => { -// await testHelper.closeAccount(config.client, config.creatorAccount, config.openAccount); -// config.creatorAccount = config.oldCreatorAccount; -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// diff --git a/lib/order/__tests__/TealAsaEscrowCancel.spec.js b/lib/order/__tests__/TealAsaEscrowCancel.spec.js index d67555ad..50596113 100644 --- a/lib/order/__tests__/TealAsaEscrowCancel.spec.js +++ b/lib/order/__tests__/TealAsaEscrowCancel.spec.js @@ -6,130 +6,64 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); -}); -// const testHelper = require('./setup.js'); -// const transactionGenerator = require('../generate_transaction_types.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const placeOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const executeAsaOrderTest = require('./teal_tests/executeASAEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const algosdk = require('algosdk'); -// -// -// const AlgodexApi = require('../algodex_api.js'); -// const constants = require('../constants.js'); -// const apiConfig = require('../../../../config.json'); -// const {createApp} = require('../../test'); -// const {transferFunds, deleteApplication, closeAccount} = require('../../../teal'); -// const {getRandomAccount} = require('../../../teal/test'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// // TODO: The negative tests need to be implemented. The commented ones out are examples but will not work with -// // this transaction type. -// const negTests = [ -// /* {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 0, field: 'appArgs', innerNum: 0, val: textEncoder.encode('execute') }, -// {txnNum: 0, field: 'appIndex', configKeyForVal: 'fakeAppId' }, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, negTxn: { -// unsignedTxnPromise: transactionGenerator.getAssetSendTxn(config.client, config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, config.assetId, false), -// senderAcct: config.maliciousAccount -// } -// }, -// {txnNum: 2, field: 'from', txnKeyForVal: 'from', txnNumForVal: 1}, //set to from escrow -// {txnNum: 2, field: 'to', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount -// } -// },*/ -// -// ]; -// -// -// describe('ASA ESCROW ORDER BOOK', () => { -// // Create App -// beforeAll(async ()=>{ -// await config.init(AlgodexApi, [apiConfig]); -// const appIndex = await createApp(config, 'buy'); -// config.setAppIndex(appIndex); -// config.setCreatorAccount(getRandomAccount()); -// await transferFunds(config.client, config.openAccount, config.creatorAccount, 2000000); -// }, JEST_MINUTE_TIMEOUT); -// -// // Delete App -// afterAll(async ()=>{ -// await deleteApplication(config.client, config.creatorAccount, config.appId); -// await closeAccount(config.client, config.creatorAccount, config.openAccount); -// await closeAccount(config.client, config.executorAccount, config.openAccount); -// await closeAccount(config.client, config.maliciousAccount, config.openAccount); -// }, JEST_MINUTE_TIMEOUT); -// test('Create asa escrow order book', async () => { -// config.creatorAccount = testHelper.getRandomAccount(); -// config.executorAccount = testHelper.getRandomAccount(); -// config.maliciousAccount = testHelper.getRandomAccount(); -// config.appId = await createAppTest.runTest(config, false); -// global.ASA_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Place asa escrow order', async () => { -// const asaAmount = 400000; -// const price = 1.25; -// const result = await placeASAOrderTest.runTest(config, asaAmount, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// -// negTests.map( (negTestTxnConfig) => { -// const testName = `Negative algo full execution order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await executeAlgoOrderTest.runFullExecTest(config, true); -// outerTxns.map( (txn) => { -// const unsignedTxn = txn.unsignedTxn; -// // console.log({unsignedTxn}); -// }); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// test('Close asa escrow order', async () => { -// const price = 1.25; -// const result = await closeASAOrderTest.runTest(config, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Delete asa escrow order book', async () => { -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); +const config = require('./TealConfig'); +const {timeout} = require('../../../lib/teal/utils'); +const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); +const JEST_MINUTE_TIMEOUT = 60 * 1000; +const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); +const accountSetup = require('./accountSetup.js'); +const accountCleanup = require('./accountCleanup'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset'); + + +describe('ASA ESCROW CANCEL', () => { + const price = 1.2; + const amount = 0.8; + + + // Create App + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + + const note = ` + Testing: TealAsaEscrowCancel + assetId: ${assetId} + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + + Creator Account is buying ${amount} LAMPC at price: ${price} Algo + `; + config.assetId = assetId; + + await accountSetup(config, 'sell', true, true, note); + await timeout(7000); + }, JEST_MINUTE_TIMEOUT * 10); + + afterAll(async () => { + await timeout(4000); + await accountCleanup(config, 'sell', true); + await destroyAsset(config.openAccount, config.assetId); + }, JEST_MINUTE_TIMEOUT); + + test( + 'Place asa escrow order', + async () => { + const result = await placeASAOrderTest.runTest(config, amount, price); + expect(result).toBeTruthy(); + await timeout(4000); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Close asa escrow order', + async () => { + const result = await closeASAOrderTest.runTest(config, price, amount); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT * 2, + ); +}); diff --git a/lib/order/__tests__/TealAsaEscrowPayCloseoutNoOptInTxn.spec.js b/lib/order/__tests__/TealAsaEscrowPayCloseoutNoOptInTxn.spec.js index 59148340..21038c1d 100644 --- a/lib/order/__tests__/TealAsaEscrowPayCloseoutNoOptInTxn.spec.js +++ b/lib/order/__tests__/TealAsaEscrowPayCloseoutNoOptInTxn.spec.js @@ -6,120 +6,70 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); -}); -// const testHelper = require('./setup.js'); -// const transactionGenerator = require('../generate_transaction_types.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const placeOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const executeAsaOrderTest = require('./teal_tests/executeASAEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const algosdk = require('algosdk'); -// -// -// const AlgodexApi = require('../algodex_api.js'); -// const constants = require('../constants.js'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// const textEncoder = new TextEncoder(); -// -// // TODO: The negative tests need to be implemented. The commented ones out are examples but will not work with -// // this transaction type. -// const negTests = [ -// /* {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 0, field: 'appArgs', innerNum: 0, val: textEncoder.encode('execute') }, -// {txnNum: 0, field: 'appIndex', configKeyForVal: 'fakeAppId' }, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, negTxn: { -// unsignedTxnPromise: transactionGenerator.getAssetSendTxn(config.client, config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, config.assetId, false), -// senderAcct: config.maliciousAccount -// } -// }, -// {txnNum: 2, field: 'from', txnKeyForVal: 'from', txnNumForVal: 1}, //set to from escrow -// {txnNum: 2, field: 'to', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount -// } -// },*/ -// -// ]; -// -// -// describe('ASA ESCROW ORDER BOOK', () => { -// test('Create asa escrow order book', async () => { -// config.creatorAccount = testHelper.getRandomAccount(); -// config.executorAccount = testHelper.getRandomAccount(); -// config.maliciousAccount = testHelper.getRandomAccount(); -// config.appId = await createAppTest.runTest(config, false, true); -// global.ASA_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Place asa escrow order', async () => { -// const asaAmount = 400000; -// const price = 1.25; -// const result = await placeASAOrderTest.runTest(config, asaAmount, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// -// negTests.map( (negTestTxnConfig) => { -// const testName = `Negative algo full execution order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await executeAlgoOrderTest.runFullExecTest(config, true); -// outerTxns.map( (txn) => { -// const unsignedTxn = txn.unsignedTxn; -// // console.log({unsignedTxn}); -// }); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// test('Fully execute asa escrow order (with asa opt-in)', async () => { -// let asaBalance = await testHelper.getAssetBalance(config.executorAccount.addr, config.assetId); -// expect(asaBalance).toBeGreaterThan(0); -// -// const price = 1.25; -// // The execution will cause it to be opted in -// const result = await executeAsaOrderTest.runFullExecTest(config, price); -// expect(result).toBeTruthy(); -// -// asaBalance = await testHelper.getAssetBalance(config.executorAccount.addr, config.assetId); -// expect(asaBalance).toBeGreaterThan(0); -// }, JEST_MINUTE_TIMEOUT); -// -// -// test('Delete asa escrow order book', async () => { -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); +const accountSetup = require('./accountSetup.js'); +const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); +const {timeout} = require('../../teal/utils'); +const executeASAEscrowOrderTest = require('./teal_tests/executeASAEscrowOrder'); +const JEST_MINUTE_TIMEOUT = 60 * 10000; +const config = require('./TealConfig'); +const takerAccountCleanup = require('./takerAccountCleanup'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset'); + // +describe('ASA ESCROW PAY CLOSEOUT NO OPT IN TXN', () => { + const asaAmount = 0.4; + const price = 1.25; + const executorAmount = 0.41; + + + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + + + const note = ` + Testing: TealAsaEscrowPayCloseoutNoOptInTxn + assetId: ${assetId} + + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + Executor Account: ${config.executorAccount.addr} + + Creator Account is selling ${asaAmount} LAMPC at price: ${price} Algo + Executor Account is buying ${executorAmount} LAMPC (rounding issue normally will be ${asaAmount}) + `; + config.assetId = assetId; + + await accountSetup(config, 'sell', true, true, note);// Since we're testing noOptIn on the executor account we pass true for optIn in account setup + await timeout(7000); // Eliminates race condition where future indexer calls occur before setUp step fully propogates but after it succeeds + }, JEST_MINUTE_TIMEOUT); + + afterAll(async () => { + await timeout(4000); + await takerAccountCleanup(config, 'sell', executorAmount, true); + await destroyAsset(config.openAccount, config.assetId); + }, JEST_MINUTE_TIMEOUT); + + test( + 'Place asa escrow order', + async () => { + const result = await placeASAOrderTest.runTest(config, asaAmount, price); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Closeout execute asa escrow order with noOptIn', + async () => { + const result = await executeASAEscrowOrderTest.runTest( + config, + executorAmount, + price, + ); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); +}); diff --git a/lib/order/__tests__/TealAsaEscrowPayCloseoutWithOptInTxn.spec.js b/lib/order/__tests__/TealAsaEscrowPayCloseoutWithOptInTxn.spec.js index d51ccd75..78168a9b 100644 --- a/lib/order/__tests__/TealAsaEscrowPayCloseoutWithOptInTxn.spec.js +++ b/lib/order/__tests__/TealAsaEscrowPayCloseoutWithOptInTxn.spec.js @@ -6,120 +6,69 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); -}); -// const testHelper = require('./setup.js'); -// const transactionGenerator = require('../generate_transaction_types.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const placeOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const executeAsaOrderTest = require('./teal_tests/executeASAEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const algosdk = require('algosdk'); -// -// -// const AlgodexApi = require('../algodex_api.js'); -// const constants = require('../constants.js'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// const textEncoder = new TextEncoder(); -// -// // TODO: The negative tests need to be implemented. The commented ones out are examples but will not work with -// // this transaction type. -// const negTests = [ -// /* {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 0, field: 'appArgs', innerNum: 0, val: textEncoder.encode('execute') }, -// {txnNum: 0, field: 'appIndex', configKeyForVal: 'fakeAppId' }, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, negTxn: { -// unsignedTxnPromise: transactionGenerator.getAssetSendTxn(config.client, config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, config.assetId, false), -// senderAcct: config.maliciousAccount -// } -// }, -// {txnNum: 2, field: 'from', txnKeyForVal: 'from', txnNumForVal: 1}, //set to from escrow -// {txnNum: 2, field: 'to', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount -// } -// },*/ -// -// ]; -// -// -// describe('ASA ESCROW ORDER BOOK', () => { -// test('Create asa escrow order book', async () => { -// config.creatorAccount = testHelper.getRandomAccount(); -// config.executorAccount = testHelper.getRandomAccount(); -// config.maliciousAccount = testHelper.getRandomAccount(); -// config.appId = await createAppTest.runTest(config, false, false); -// global.ASA_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Place asa escrow order', async () => { -// const asaAmount = 400000; -// const price = 1.25; -// const result = await placeASAOrderTest.runTest(config, asaAmount, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// -// negTests.map( (negTestTxnConfig) => { -// const testName = `Negative algo full execution order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await executeAlgoOrderTest.runFullExecTest(config, true); -// outerTxns.map( (txn) => { -// const unsignedTxn = txn.unsignedTxn; -// // console.log({unsignedTxn}); -// }); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// test('Fully execute asa escrow order (with asa opt-in)', async () => { -// let asaBalance = await testHelper.getAssetBalance(config.executorAccount.addr, config.assetId); -// expect(asaBalance).toBeNull(); -// -// const price = 1.25; -// // The execution will cause it to be opted in -// const result = await executeAsaOrderTest.runFullExecTest(config, price); -// expect(result).toBeTruthy(); -// -// asaBalance = await testHelper.getAssetBalance(config.executorAccount.addr, config.assetId); -// expect(asaBalance).toBeGreaterThan(0); -// }, JEST_MINUTE_TIMEOUT); -// -// -// test('Delete asa escrow order book', async () => { -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); +const accountSetup = require('./accountSetup.js'); +const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); +const {timeout} = require('../../teal/utils'); +const executeASAEscrowOrderTest = require('./teal_tests/executeASAEscrowOrder'); +const JEST_MINUTE_TIMEOUT = 60 * 10000; +const config = require('./TealConfig'); +const takerAccountCleanup = require('./takerAccountCleanup'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset'); + // +describe('ASA ESCROW PAY CLOSEOUT WITH OPT IN TXN', () => { + const asaAmount = 0.4; + const price = 1.25; + const executorAmount = 0.41; + + + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + + + const note = ` + Testing: TealAsaEscrowPayCloseoutWithOptInTxn + assetId: ${assetId} + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + Executor Account: ${config.executorAccount.addr} + + Creator Account is selling ${asaAmount} LAMPC at price: ${price} Algo + Executor Account is buying ${executorAmount} LAMPC (rounding issue normally will be ${asaAmount}) + `; + config.assetId = assetId; + + await accountSetup(config, 'sell', false, true, note);// Since we're testing withOptIn on the executor account we pass false for optIn in account setup + await timeout(7000); // Eliminates race condition where future indexer calls occur before setUp step fully propogates but after it succeeds + }, JEST_MINUTE_TIMEOUT); + + afterAll(async () => { + await timeout(4000); + await takerAccountCleanup(config, 'sell', executorAmount, true); + await destroyAsset(config.openAccount, config.assetId); + }, JEST_MINUTE_TIMEOUT); + + test( + 'Place asa escrow order', + async () => { + const result = await placeASAOrderTest.runTest(config, asaAmount, price); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Closeout execute asa escrow order with Optin', + async () => { + const result = await executeASAEscrowOrderTest.runTest( + config, + executorAmount, + price, + ); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); +}); diff --git a/lib/order/__tests__/TealAsaEscrowPayPartialNoOptInTxn.spec.js b/lib/order/__tests__/TealAsaEscrowPayPartialNoOptInTxn.spec.js index 9f8dd36c..efcecab7 100644 --- a/lib/order/__tests__/TealAsaEscrowPayPartialNoOptInTxn.spec.js +++ b/lib/order/__tests__/TealAsaEscrowPayPartialNoOptInTxn.spec.js @@ -6,121 +6,83 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); +const accountSetup = require('./accountSetup.js'); +const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); +const {timeout} = require('../../teal/utils'); +const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); +const executeASAEscrowOrderTest = require('./teal_tests/executeASAEscrowOrder'); +const JEST_MINUTE_TIMEOUT = 60 * 10000; +const config = require('./TealConfig'); +const takerAccountCleanup = require('./takerAccountCleanup'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset'); + +describe('ASA ESCROW PAY PARTIAL NO OPT IN TXN', () => { + const asaAmount = 0.4; + const price = 1.20; + + const executorAmount = 0.2; + + + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + + const note = ` + Testing: TealAsaEscrowPayPartialnoOptInTxn + assetId: ${assetId} + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + Executor Account: ${config.executorAccount.addr} + + Creator Account is selling ${asaAmount} LAMPC at price: ${price} Algo + Executor Account is buying ${executorAmount} LAMPC + `; + config.assetId = assetId; + + await accountSetup(config, 'sell', true, true, note); + await timeout(7000); // Eliminates race condition where future indexer calls occur before setUp step fully propogates but after it succeeds + }, JEST_MINUTE_TIMEOUT); + + afterAll(async () => { + await timeout(4000); + await takerAccountCleanup(config, 'sell', executorAmount); + await destroyAsset(config.openAccount, config.assetId); + }, JEST_MINUTE_TIMEOUT); + + test( + 'Place asa escrow order', + async () => { + const result = await placeASAOrderTest.runTest(config, asaAmount, price); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Partially execute asa escrow order (no opt-in txn)', + async () => { + const result = await executeASAEscrowOrderTest.runTest( + config, + executorAmount, + price, + ); + expect(result).toBeTruthy(); + await timeout(4000); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Close asa escrow order', + async () => { + const result = await closeASAOrderTest.runTest( + config, + price, + asaAmount - executorAmount, + ); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); }); -// const testHelper = require('./setup.js'); -// const transactionGenerator = require('../generate_transaction_types.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const placeOrderTest = require('./teal_tests/placeAlgoEscrowOrder.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const executeAsaOrderTest = require('./teal_tests/executeASAEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeOrderTest = require('./teal_tests/closeAlgoEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const algosdk = require('algosdk'); -// -// -// const AlgodexApi = require('../algodex_api.js'); -// const constants = require('../constants.js'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// const textEncoder = new TextEncoder(); -// -// // TODO: The negative tests need to be implemented. The commented ones out are examples but will not work with -// // this transaction type. -// const negTests = [ -// /* {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 0, field: 'appArgs', innerNum: 0, val: textEncoder.encode('execute') }, -// {txnNum: 0, field: 'appIndex', configKeyForVal: 'fakeAppId' }, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, negTxn: { -// unsignedTxnPromise: transactionGenerator.getAssetSendTxn(config.client, config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, config.assetId, false), -// senderAcct: config.maliciousAccount -// } -// }, -// {txnNum: 2, field: 'from', txnKeyForVal: 'from', txnNumForVal: 1}, //set to from escrow -// {txnNum: 2, field: 'to', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount -// } -// },*/ -// -// ]; -// -// -// describe('ASA ESCROW ORDER BOOK', () => { -// test('Create asa escrow order book', async () => { -// config.creatorAccount = testHelper.getRandomAccount(); -// config.executorAccount = testHelper.getRandomAccount(); -// config.maliciousAccount = testHelper.getRandomAccount(); -// config.appId = await createAppTest.runTest(config, false, true); -// global.ASA_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Place asa escrow order', async () => { -// const asaAmount = 400000; -// const price = 1.25; -// const result = await placeASAOrderTest.runTest(config, asaAmount, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// negTests.map( (negTestTxnConfig) => { -// const testName = `Negative algo full execution order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await executeAlgoOrderTest.runFullExecTest(config, true); -// outerTxns.map( (txn) => { -// const unsignedTxn = txn.unsignedTxn; -// // console.log({unsignedTxn}); -// }); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// test('Partially execute asa escrow order (no opt-in txn)', async () => { -// const asaAmountReceiving = 80000; -// const price = 1.25; -// const asaBalance = await testHelper.getAssetBalance(config.executorAccount.addr, config.assetId); -// expect(asaBalance).toBeGreaterThan(0); -// -// const result = await executeAsaOrderTest.runPartialExecTest(config, asaAmountReceiving, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Close asa escrow order', async () => { -// const price = 1.25; -// const result = await closeASAOrderTest.runTest(config, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Delete asa escrow order book', async () => { -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// diff --git a/lib/order/__tests__/TealAsaEscrowPayPartialWithOptInTxn.spec.js b/lib/order/__tests__/TealAsaEscrowPayPartialWithOptInTxn.spec.js index c06c446f..829e1545 100644 --- a/lib/order/__tests__/TealAsaEscrowPayPartialWithOptInTxn.spec.js +++ b/lib/order/__tests__/TealAsaEscrowPayPartialWithOptInTxn.spec.js @@ -6,114 +6,82 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); +const accountSetup = require('./accountSetup.js'); +const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); +const {timeout} = require('../../teal/utils'); +const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); +const executeASAEscrowOrderTest = require('./teal_tests/executeASAEscrowOrder'); +const JEST_MINUTE_TIMEOUT = 60 * 1000; +const config = require('./TealConfig'); +const takerAccountCleanup = require('./takerAccountCleanup'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset'); + +describe('ASA ESCROW PAY PARTIAL WITH OPT IN TXN', () => { + const asaAmount = 0.4; + const price = 1.20; + const executorAmount = 0.2; + + + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + + + const note = ` + Testing: TealAsaEscrowPayPartialWithOptInTxn + assetId: ${assetId} + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + Executor Account: ${config.executorAccount.addr} + + Creator Account is selling ${asaAmount} LAMPC at price: ${price} Algo + Executor Account is buying ${executorAmount} LAMPC + `; + config.assetId = assetId; + await accountSetup(config, 'sell', false, true, note);// Since we're testing withOptIn on the executor account we pass false for optIn in account setup + await timeout(7000); // Eliminates race condition where future indexer calls occur before setUp step fully propogates but after it succeeds + }, JEST_MINUTE_TIMEOUT); + + afterAll(async () => { + await timeout(4000); + await takerAccountCleanup(config, 'sell', executorAmount); + await destroyAsset(config.openAccount, config.assetId); + }, JEST_MINUTE_TIMEOUT); + + test( + 'Place asa escrow order', + async () => { + const result = await placeASAOrderTest.runTest(config, asaAmount, price); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Partially execute asa escrow order with Optin', + async () => { + const result = await executeASAEscrowOrderTest.runTest( + config, + executorAmount, + price, + ); + expect(result).toBeTruthy(); + await timeout(4000); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Close asa escrow order', + async () => { + const result = await closeASAOrderTest.runTest( + config, + price, + asaAmount - executorAmount, + ); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); }); -// const testHelper = require('./setup.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const executeAsaOrderTest = require('./teal_tests/executeASAEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const constants = require('../constants.js'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// const textEncoder = new TextEncoder(); -// -// // TODO: The negative tests need to be implemented. The commented ones out are examples but will not work with -// // this transaction type. -// const negTests = [ -// /* {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 0, field: 'appArgs', innerNum: 0, val: textEncoder.encode('execute') }, -// {txnNum: 0, field: 'appIndex', configKeyForVal: 'fakeAppId' }, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, negTxn: { -// unsignedTxnPromise: transactionGenerator.getAssetSendTxn(config.client, config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, config.assetId, false), -// senderAcct: config.maliciousAccount -// } -// }, -// {txnNum: 2, field: 'from', txnKeyForVal: 'from', txnNumForVal: 1}, //set to from escrow -// {txnNum: 2, field: 'to', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount -// } -// },*/ -// -// ]; -// -// -// describe('ASA ESCROW ORDER BOOK', () => { -// test('Create asa escrow order book', async () => { -// config.creatorAccount = testHelper.getRandomAccount(); -// config.executorAccount = testHelper.getRandomAccount(); -// config.maliciousAccount = testHelper.getRandomAccount(); -// config.appId = await createAppTest.runTest(config, false, false); -// global.ASA_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Place asa escrow order', async () => { -// const asaAmount = 400000; -// const price = 1.25; -// const result = await placeASAOrderTest.runTest(config, asaAmount, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// negTests.map( (negTestTxnConfig) => { -// const testName = `Negative algo full execution order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await executeAlgoOrderTest.runFullExecTest(config, true); -// outerTxns.map( (txn) => { -// const unsignedTxn = txn.unsignedTxn; -// // console.log({unsignedTxn}); -// }); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// test('Partially execute asa escrow order (with opt-in txn)', async () => { -// const asaAmountReceiving = 80000; -// const price = 1.25; -// const asaBalance = await testHelper.getAssetBalance(config.executorAccount.addr, config.assetId); -// expect(asaBalance).toBeNull(); // has not opted in yet -// -// const result = await executeAsaOrderTest.runPartialExecTest(config, asaAmountReceiving, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Close asa escrow order', async () => { -// const price = 1.25; -// const result = await closeASAOrderTest.runTest(config, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Delete asa escrow order book', async () => { -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// diff --git a/lib/order/__tests__/TealAsaEscrowPlace.spec.js b/lib/order/__tests__/TealAsaEscrowPlace.spec.js index 85bee055..0a614255 100644 --- a/lib/order/__tests__/TealAsaEscrowPlace.spec.js +++ b/lib/order/__tests__/TealAsaEscrowPlace.spec.js @@ -6,104 +6,77 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -it('should fix these tests', ()=>{ - const isBroken = true; - expect(isBroken).toEqual(true); +/* eslint-disable */ + + +const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); +const constants = require('./constants.js'); +const accountSetup = require('./accountSetup.js'); +const accountCleanup = require('./accountCleanup.js'); +const JEST_MINUTE_TIMEOUT = 60 * 1000; +const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); +const generateAsset = require('./GenerateAsset'); +const destroyAsset = require('./DestroyAsset') + +const config = require('./TealConfig.js'); + +console.log( + 'DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE, +); + +/* eslint-disable valid-jsdoc */ +describe('ASA ESCROW PLACE', () => { + function timeout(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + const asaAmount = 0.4; + const price = 1.25; + + + beforeAll(async () => { + const assetId = await generateAsset(config.openAccount); + console.log(assetId); + + const note = ` + Testing: TealAsaEscrowPlace + assetId: ${assetId} + Open Account: ${config.openAccount.addr} + Creator Account: ${config.creatorAccount.addr} + Creator Account is selling ${asaAmount} LAMPC at price: ${price} Algo + `; + config.assetId = assetId + + await accountSetup(config, 'sell', true, false, note); + await timeout(7000); // Eliminates race condition where future indexer calls occur before setUp step fully propogates but after it succeeds + }, JEST_MINUTE_TIMEOUT); + + afterAll(async () => { + await timeout(4000); + await accountCleanup(config, 'sell', true); + await destroyAsset(config.openAccount, config.assetId); + + }, JEST_MINUTE_TIMEOUT); + + + test( + 'Place asa escrow order', + async () => { + + const result = await placeASAOrderTest.runTest(config, asaAmount, price); + expect(result).toBeTruthy(); + await timeout(4000); + }, + JEST_MINUTE_TIMEOUT, + ); + + test( + 'Close asa escrow order', + async () => { + // const price = 1.25; + const result = await closeASAOrderTest.runTest(config, price, asaAmount); + expect(result).toBeTruthy(); + }, + JEST_MINUTE_TIMEOUT, + ); }); -// const testHelper = require('./setup.js'); -// const createAppTest = require('./teal_tests/createAppTest.js'); -// const deleteAppTest = require('./teal_tests/deleteAppTest.js'); -// const executeAlgoOrderTest = require('./teal_tests/executeAlgoEscrowOrder.js'); -// const placeASAOrderTest = require('./teal_tests/placeASAEscrowOrder.js'); -// const closeASAOrderTest = require('./teal_tests/closeASAEscrowOrder.js'); -// const constants = require('../constants.js'); -// const JEST_MINUTE_TIMEOUT = 60 * 1000; -// -// const config = { -// appId: -1, -// creatorAccount: testHelper.getRandomAccount(), -// executorAccount: testHelper.getRandomAccount(), -// openAccount: testHelper.getOpenAccount(), -// maliciousAccount: testHelper.getRandomAccount(), -// client: testHelper.getLocalClient(), -// assetId: 66711302, -// }; -// -// console.log('DEBUG_SMART_CONTRACT_SOURCE is: ' + constants.DEBUG_SMART_CONTRACT_SOURCE); -// -// const textEncoder = new TextEncoder(); -// -// // TODO: The negative tests need to be implemented. The commented ones out are examples but will not work with -// // this transaction type. -// const negTests = [ -// /* {txnNum: 0, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 0, field: 'appArgs', innerNum: 0, val: textEncoder.encode('execute') }, -// {txnNum: 0, field: 'appIndex', configKeyForVal: 'fakeAppId' }, -// {txnNum: 0, field: 'appOnComplete', val: 0}, -// {txnNum: 1, field: 'from', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, field: 'closeRemainderTo', val: algosdk.decodeAddress(config.maliciousAccount.addr) }, -// {txnNum: 1, negTxn: { -// unsignedTxnPromise: transactionGenerator.getAssetSendTxn(config.client, config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, config.assetId, false), -// senderAcct: config.maliciousAccount -// } -// }, -// {txnNum: 2, field: 'from', txnKeyForVal: 'from', txnNumForVal: 1}, //set to from escrow -// {txnNum: 2, field: 'to', val: algosdk.decodeAddress(config.maliciousAccount.addr)}, -// {txnNum: 2, negTxn: { -// unsignedTxnPromise: transactionGenerator.getPayTxn(config.client, -// config.maliciousAccount.addr, config.maliciousAccount.addr, -// 1000, false), -// senderAcct: config.maliciousAccount -// } -// },*/ -// -// ]; -// -// -// describe('ASA ESCROW ORDER BOOK', () => { -// test('Create asa escrow order book', async () => { -// config.creatorAccount = testHelper.getRandomAccount(); -// config.executorAccount = testHelper.getRandomAccount(); -// config.maliciousAccount = testHelper.getRandomAccount(); -// config.appId = await createAppTest.runTest(config, false); -// global.ASA_ESCROW_APP_ID = config.appId; -// expect(config.appId).toBeGreaterThan(0); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Place asa escrow order', async () => { -// const asaAmount = 400000; -// const price = 1.25; -// const result = await placeASAOrderTest.runTest(config, asaAmount, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// negTests.map( (negTestTxnConfig) => { -// const testName = `Negative algo full execution order test: txnNum: ${negTestTxnConfig.txnNum} field: ${negTestTxnConfig.field} val: ${negTestTxnConfig.val}`; -// test(testName, async () => { -// if (negTestTxnConfig.negTxn) { -// negTestTxnConfig.negTxn.unsignedTxn = await negTestTxnConfig.negTxn.unsignedTxnPromise; -// } -// const outerTxns = await executeAlgoOrderTest.runFullExecTest(config, true); -// outerTxns.map( (txn) => { -// const unsignedTxn = txn.unsignedTxn; -// // console.log({unsignedTxn}); -// }); -// const result = await testHelper.runNegativeTest(config, config.client, outerTxns, negTestTxnConfig); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); -// -// -// test('Close asa escrow order', async () => { -// const price = 1.25; -// const result = await closeASAOrderTest.runTest(config, price); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// -// test('Delete asa escrow order book', async () => { -// const result = await deleteAppTest.runTest(config); -// expect(result).toBeTruthy(); -// }, JEST_MINUTE_TIMEOUT); -// }); // diff --git a/lib/order/__tests__/TealConfig.js b/lib/order/__tests__/TealConfig.js new file mode 100644 index 00000000..020e598c --- /dev/null +++ b/lib/order/__tests__/TealConfig.js @@ -0,0 +1,15 @@ +const testHelper = require('./setup.js'); +const connector = require('../../wallet/connectors/AlgoSDK'); + +const config = { + appId: -1, + creatorAccount: testHelper.getRandomAccount(), + executorAccount: testHelper.getRandomAccount(), + openAccount: testHelper.getOpenAccount(), + maliciousAccount: testHelper.getRandomAccount(), + client: testHelper.getLocalClient(), + connector: connector, + assetId: 66711302, +}; + +module.exports = config; diff --git a/lib/order/__tests__/accountCleanup.js b/lib/order/__tests__/accountCleanup.js new file mode 100644 index 00000000..f1f629b6 --- /dev/null +++ b/lib/order/__tests__/accountCleanup.js @@ -0,0 +1,44 @@ +const {transferFunds, transferASA} = require('../../teal/utils'); + +/** + * + * @param {TestConfig} config + * @param {String} type + * @param {boolean} optIn + * @param {boolean} newCreator + * @return {Promise} + */ +async function cleanupAccounts( + config, + type, + optIn = false, + newCreator = false, +) { + const { + client, + openAccount, + creatorAccount, + assetId, + } = config; + + if (type === 'sell') { + // escrowPlaceOrder + await transferASA(client, creatorAccount, openAccount, 2000000, assetId); // transfer back ASA + await transferFunds(client, creatorAccount, openAccount, 1500000); // transfer original algo + } + + if (type === 'buy') { + await transferFunds(client, creatorAccount, openAccount, 1750000); // transfer original algo + } + + // if (optIn) { + // await transferASA(client, executorAccount, executorAccount, 0, config.assetIndex); // opt in transaction + // await transferASA(client, openAccount, executorAccount, 2000000, config.assetIndex); // 5 algos + // } + + // await transferFunds(client, openAccount, maliciousAccount, 5000000); // 5 algos + // await transferASA(client, maliciousAccount, maliciousAccount, 0, config.assetIndex); // opt in transaction + // await transferASA(client, openAccount, maliciousAccount, 2000000, config.assetIndex); // 5 algos +} + +module.exports = cleanupAccounts; diff --git a/lib/order/__tests__/accountSetup.js b/lib/order/__tests__/accountSetup.js new file mode 100644 index 00000000..0fedfa8d --- /dev/null +++ b/lib/order/__tests__/accountSetup.js @@ -0,0 +1,37 @@ +const initAccounts = require('../../teal/test/initAccounts'); +const initExecutor = require('../../teal/test/initExecutor'); +const enc = require('../../utils/encoder'); + + +const logger = require('../../logger'); + +/** + * + * @param {TestConfig} config Test Configuration + * @param {'buy'|'sell'} type Type of Order + * @param {boolean} [optIn] Opt In + * @param {boolean} [executor] Parameter for whether or not to set up an executor account to test taker orders + * @param {boolean} [note] information related to the test to be included in the note field + * + * @return {Promise} + */ +async function accountSetup(config, type, optIn = false, executor, note) { + logger.info({type, optIn, executor}, `order.test.beforeAll()`); + if (typeof type !== 'string' || !['buy', 'sell'].includes(type)) { + throw new TypeError('Must have valid type!'); + } + + const encodedNote = typeof note !== 'undefined' ? enc.encode(note) : undefined; + + // Initalize API Client + // await config.init(AlgodexApi, [apiConfig]); + + + // Initialize Accounts and Configuration + await initAccounts(config, type, optIn, encodedNote); + if (executor) { + await initExecutor(config, type, optIn, encodedNote); + } +} + +module.exports = accountSetup; diff --git a/lib/order/__tests__/afterAll.js b/lib/order/__tests__/afterAll.js deleted file mode 100644 index d7d7793f..00000000 --- a/lib/order/__tests__/afterAll.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2021-2022 Algodex VASP (BVI) Corp. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -const {deleteApplication, closeAccount} = require('../../teal'); - -/** - * - * @todo Refactor to config.apps and remove all - * @param {TestConfig} config - * @return {Promise} - */ -async function afterAll(config) { - const { - client, - openAccount, - creatorAccount, - executorAccount, - maliciousAccount, - appIndex, - fakeAppIndex, - oldCreatorAccount, - } = config; - - const _account = typeof oldCreatorAccount !== 'undefined' ? - oldCreatorAccount : - creatorAccount; - - await deleteApplication(client, _account, appIndex); - - if (fakeAppIndex) { - await deleteApplication(client, _account, fakeAppIndex); - } - - await closeAccount(client, creatorAccount, openAccount); - await closeAccount(client, executorAccount, openAccount); - await closeAccount(client, maliciousAccount, openAccount); -} - -module.exports = afterAll; diff --git a/lib/order/__tests__/asa_dex_teal.js b/lib/order/__tests__/asa_dex_teal.js new file mode 100644 index 00000000..b13bf7a8 --- /dev/null +++ b/lib/order/__tests__/asa_dex_teal.js @@ -0,0 +1,333 @@ +// /////////////////////////// +// Alexander Trefonas // +// 7/9/2021 // +// Copyright Algodev Inc // +// All Rights Reserved. // +// /////////////////////////// + +const AsaOrderbookTeal = { + + getClearProgram: function getClearProgram() { + const clearProgram = + ` + #pragma version 2 + // This program clears program state. + // This will clear local state for any escrow accounts that call this from a ClearState transaction, + // the logic of which is contained within the stateless contracts as part of a Close Out (Cancel Order) operation. + // We use ClearState instead of CloseOut so that the order book cannot prevent an escrow from closing out. + int 1 + ` + ; + return clearProgram; + }, + + getASAOrderBookApprovalProgram: function getASAOrderBookApprovalProgram() { + // stateful DEX contract + // This is for the order book + return ` + //////////////////////////////////////////////// + // STATEFUL CONTRACT / + // ORDER BOOK FOR ASA ESCROWS (SELL ORDERS) / + //////////////////////////////////////////////// + #pragma version 4 + // check if the app is being created + // if so save creator + int 0 + txn ApplicationID + == + bz not_creation + byte "Creator" + txn Sender + app_global_put + int 1 + return + not_creation: + int DeleteApplication + txn OnCompletion + == + bz not_deletion + byte "Creator" // verify creator is deleting app + app_global_get + txn Sender + == + assert + int 1 + return + + not_deletion: + + int UpdateApplication // check if this is update + txn OnCompletion + == + bz not_update + + byte "Creator" // verify that the creator is making the call + app_global_get + txn Sender + == + assert + int 1 + return + not_update: + txna ApplicationArgs 0 + byte "open" + == + bnz open + txna ApplicationArgs 0 + byte "execute" + == + bnz execute + txna ApplicationArgs 0 + byte "execute_with_closeout" + == + bnz execute_with_closeout + err + // function to check for ASA opt in transaction + check_asa_optin: + gtxn 2 TypeEnum + int axfer + == + gtxn 2 AssetAmount + int 0 + == + && + gtxn 2 Sender + gtxn 2 AssetReceiver + == + && + gtxn 2 AssetCloseTo + global ZeroAddress + == + && + gtxn 2 Sender + txn Sender // Sender must come from the user's wallet, not the escrow + != // should *not* be originating from escrow + && + store 0 //this will store the next transaction offset depending if opt in exists + load 0 + int 2 + + + store 2 // store offset of transaction 2, depending on if opt-in exists + load 0 + int 3 + + + store 3 // store offset of transaction 3, depending on if opt-in exists + retsub + + /////////////////////////////////////////////////////////////////////// + // OPEN - ORDER BOOK OPT IN & REGISTRATION + // Placing an ASA Escrow Order. The escrow opts into the order book. + /////////////////////////////////////////////////////////////////////// + // TXN 0 - SELLER TO ESCROW: pay transaction into escrow + // TXN 1 - ESCROW TO ORDERBOOK: application opt in + // TXN 2 - ESCROW TO ESCROW: asset opt in + // TXN 3 - SELLER TO ESCROW: asset transfer + open: + int OptIn + txn OnCompletion + == + global GroupSize + int 4 + == + && + assert + + gtxn 0 Sender + gtxn 3 Sender + == + assert + int 0 //address index. This is the Sender of this transaction. + txn ApplicationID //current smart contract + txna ApplicationArgs 1 // 2nd txn app arg is order number + app_local_get_ex + bnz ret_success // if the value already exists return without setting anything + pop + int 0 //address index. This is the Sender of this transaction. + txna ApplicationArgs 1 //order number + int 1 // value - just set to 1 + app_local_put // store the ordernumber as the key + int 0 //address index. This is the Sender of this transaction. + byte "creator" //creator key + gtxn 0 Sender // store creator as value. This is the sender of the pay transaction + app_local_put + int 0 //address index. This is the Sender of this transaction. + byte "version" //store version + txna ApplicationArgs 2 //version + int 0 + getbyte + app_local_put // store the version + ret_success: + int 1 + return + ////////////////////////////////////////////////////////////////////////////// + // EXECUTE (partial) + // Partial execution of an ASA escrow, where an ASA balance remains in it + ////////////////////////////////////////////////////////////////////////////// + // TXN 0 - ESCROW TO ORDERBOOK: Application call to execute + // TXN 1 - BUYER TO SELLER: Pay transaction (from buyer/executor to escrow owner) + // TXN 2 - BUYER TO BUYER: (Optional) asset opt-in transaction (for buyer/executor) + // TXN 2/3 - ESCROW TO BUYER: Asset transfer (from escrow to buyer/executor) + // TXN 3/4 - BUYER TO ESCROW: Pay transaction for fee refund (from buyer/executor to escrow) + execute: + txn OnCompletion //FIXME check OnCompletion of each individual transaction + int CloseOut + == + txn OnCompletion + int NoOp + == + || + assert + + callsub check_asa_optin // this will store transaction offsets into registers if the asa opt-in exists or not + txn Sender + int 0 // foreign asset id 0 + asset_holding_get AssetBalance // pushes 1 for success, then asset onto stack + assert //make sure asset exists + load 2 + gtxns AssetAmount + > // The asset balance should be greater than or equal to the amount transferred. Otherwise should be with closeout + assert + global GroupSize + int 4 + == + global GroupSize //group size can be 5 for asset opt-in + int 5 + == + || + assert + gtxn 0 TypeEnum // First Transaction must be a call to a stateful contract + int appl + == + gtxn 1 TypeEnum // The second transaction must be a payment transaction + int pay + == + && + assert + + load 2 + gtxns TypeEnum //The next transaction must be an asset transfer + int axfer + == + assert + load 3 + gtxns TypeEnum + int pay + == + assert + int 0 // Escrow account containing order. This is the Sender of this transaction. + txn ApplicationID // Current stateful smart contract + txna ApplicationArgs 1 // 2nd argument is order number + app_local_get_ex + assert // If the value doesnt exists fail + pop + int 0 // Escrow account containing order. This is the Sender of this transaction. + txn ApplicationID // Current stateful smart contract + byte "creator" + app_local_get_ex // returns if it exists and the creator + assert // If the value doesnt exist fail + txna Accounts 1 // account arg is order creator + == + assert + global ZeroAddress + gtxn 1 CloseRemainderTo + == + assert + int 1 + return + ///////////////////////////////////////////////////////////////////////////////////////////////// + // EXECUTE WITH CLOSE + // Full order execution where the remaining minimum algo balance is closed to the escrow owner + ///////////////////////////////////////////////////////////////////////////////////////////////// + // TXN 0 - ESCROW TO ORDERBOOK: Application call to execute + // TXN 1 - BUYER TO SELLER: Pay transaction (from buyer/executor to escrow owner) + // TXN 2 - BUYER TO BUYER: (Optional) asset opt-in transaction (for buyer/executor) + // TXN 2/3 - ESCROW TO BUYER: Asset transfer (from escrow to buyer/executor) + // - closes out any remaining ASA to seller (escrow owner) as well + // TXN 3/4 - ESCROW TO SELLER: Pay transaction to close out to escrow owner + execute_with_closeout: + txn OnCompletion + int CloseOut + == + bz fail2 + callsub check_asa_optin // this will store transaction offsets into registers if the asa opt-in exists or not + txn Sender + int 0 // foreign asset id 0 + asset_holding_get AssetBalance // pushes 1 for success, then asset onto stack + assert //make sure asset exists + load 2 + gtxns AssetAmount + == // Check we are going to transfer the entire ASA amount to the buyer. Otherwise should be a partial execute + assert + global GroupSize + int 4 + == + global GroupSize //group size can be 5 for asset opt-in + int 5 + == + || + assert + gtxn 0 TypeEnum // First Transaction must be a call to a stateful contract + int appl + == + gtxn 1 TypeEnum // The second transaction must be a payment transaction + int pay + == + && + assert + load 2 + gtxns TypeEnum //The next transaction must be an asset transfer + int axfer + == + assert + load 3 // The last transaction must be a payment transfer + gtxns TypeEnum + int pay + == + assert + int 0 // Escrow account containing order. This is the Sender of this transaction. + txn ApplicationID // Current stateful smart contract + txna ApplicationArgs 1 // 2nd argument is order number + app_local_get_ex + bz fail2 // If the value doesnt exist fail + pop + int 0 // Escrow account containing order. This is the Sender of this transaction. + txn ApplicationID // Current stateful smart contract + byte "creator" + app_local_get_ex // returns if it exists and the creator + assert // If the value doesnt exist fail + txna Accounts 1 // account arg is order creator + == + assert + int 0 // Escrow account containing order. This is the Sender of this transaction. + txn ApplicationID // Current stateful smart contract + byte "version" + app_local_get_ex + assert // If the value doesnt exists fail + pop + global ZeroAddress + gtxn 1 CloseRemainderTo + == + bnz ret_success3 + int 0 //escrow account containing order. This is the Sender of this transaction. + txna ApplicationArgs 1 // order details + app_local_del // Delete the ordernumber + int 0 // escrow account containing order + byte "creator" + app_local_del // Delete the creator + int 0 // escrow account containing order + byte "version" // Delete the version + app_local_del + ret_success3: + int 1 + return + fail2: + int 0 + return + + + + `; + }, +}; + +module.exports = AsaOrderbookTeal; diff --git a/lib/order/__tests__/beforeAll.js b/lib/order/__tests__/beforeAll.js deleted file mode 100644 index b5b6bdbe..00000000 --- a/lib/order/__tests__/beforeAll.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2021-2022 Algodex VASP (BVI) Corp. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -const algosdk = require('algosdk'); -const txns = require('../txns'); -const AlgodexApi = require('../../AlgodexApi'); -const apiConfig = require('../../../config.json'); -const initAccounts = require('../../teal/test/initAccounts'); -const logger = require('../../logger'); -/** - * - * @param {TestConfig} config Test Configuration - * @param {'buy'|'sell'} type Type of Order - * @param {boolean} [optIn] Opt In - * @param {boolean} [newCreator] create new creator account - * @return {Promise} - */ -async function beforeAll(config, type, optIn = false, newCreator = false) { - logger.info({type, optIn, newCreator}, `order.test.beforeAll()`); - if (typeof type !== 'string' || !['buy', 'sell'].includes(type)) { - throw new TypeError('Must have valid type!'); - } - - // Initalize API Client - await config.init(AlgodexApi, [apiConfig]); - - // Initialize Accounts and Configuration - await initAccounts(config, optIn, newCreator); - - const {client, creatorAccount} = config; - const createTxn = await txns.makeApplicationCreateTxn( - client, - type, - creatorAccount, - config.suggestedParams, - ); - const txId = createTxn.txID().toString(); - - const signedTxn = createTxn.signTxn(creatorAccount.sk); - - await client.sendRawTransaction(signedTxn).do(); - - // Wait for confirmation - await algosdk.waitForConfirmation(client, txId, 10); - - // display results - const transactionResponse = await client.pendingTransactionInformation(txId).do(); - - config.setAppIndex(transactionResponse['application-index']); -} - -module.exports = beforeAll; diff --git a/lib/order/__tests__/constants.js b/lib/order/__tests__/constants.js new file mode 100644 index 00000000..0eb5ed6b --- /dev/null +++ b/lib/order/__tests__/constants.js @@ -0,0 +1,61 @@ +// /////////////////////////// +// Alexander Trefonas // +// 7/9/2021 // +// Copyright Algodev Inc // +// All Rights Reserved. // +// /////////////////////////// + + +module.exports = { + DEBUG: 1, + DEBUG_SMART_CONTRACT_SOURCE: process.env.NEXT_PUBLIC_DEBUG_SMART_CONTRACT_SOURCE ? parseInt(process.env.NEXT_PUBLIC_DEBUG_SMART_CONTRACT_SOURCE) : 0, + INFO_SERVER: process.env.ALGODEX_INFO_HOST, + + ESCROW_CONTRACT_VERSION: 6, + ORDERBOOK_CONTRACT_VERSION: 5, + MIN_ESCROW_BALANCE: 500000, + MIN_ASA_ESCROW_BALANCE: 500000, + + LOCAL_ALGOD_SERVER: process.env.ALGODEX_ALGOD_SERVER || process.env.NEXT_PUBLIC_ALGODEX_ALGOD_SERVER || 'https://node.testnet.algoexplorerapi.io', + LOCAL_ALGOD_PORT: process.env.ALGODEX_ALGOD_PORT || process.env.NEXT_PUBLIC_ALGODEX_ALGOD_PORT || '', + LOCAL_ALGOD_TOKEN: process.env.ALGODEX_ALGOD_TOKEN || process.env.NEXT_PUBLIC_ALGODEX_ALGOD_TOKEN || '', + LOCAL_BACKEND_API: 'http://localhost/algodex-backend', + LOCAL_INDEXER_SERVER: 'https://algoindexer.testnet.algoexplorerapi.io', + LOCAL_INDEXER_PORT: '', + LOCAL_INDEXER_TOKEN: '', + // intentionally same as test, assuming testnet being used on local setup + LOCAL_ALGO_ORDERBOOK_APPID: 18988007, + LOCAL_ASA_ORDERBOOK_APPID: 18988134, + // const indexer_server = "http://localhost"; + // const indexer_port = "8980"; + + TEST_ALGOD_SERVER: ('ALGODEX_ALGOD_SERVER' in process.env) ? process.env.ALGODEX_ALGOD_SERVER : 'https://node.testnet.algoexplorerapi.io', + TEST_ALGOD_PORT: ('ALGODEX_ALGOD_PORT' in process.env) ? process.env.ALGODEX_ALGOD_PORT : '', + TEST_ALGOD_TOKEN: ('ALGODEX_ALGOD_TOKEN' in process.env) ? process.env.ALGODEX_ALGOD_TOKEN : '', + TEST_BACKEND_API: 'https://api-testnet.algodex.com/algodex-backend', + TEST_INDEXER_SERVER: 'https://algoindexer.testnet.algoexplorerapi.io', + TEST_INDEXER_PORT: '', + TEST_INDEXER_TOKEN: '', + TEST_ALGO_ORDERBOOK_APPID: 16021155, + TEST_ASA_ORDERBOOK_APPID: 16021157, + + PUBLIC_TEST_ALGOD_SERVER: ('ALGODEX_ALGOD_SERVER' in process.env) ? process.env.ALGODEX_ALGOD_SERVER : 'https://node.testnet.algoexplorerapi.io', + PUBLIC_TEST_ALGOD_PORT: ('ALGODEX_ALGOD_PORT' in process.env) ? process.env.ALGODEX_ALGOD_PORT : '', + PUBLIC_TEST_ALGOD_TOKEN: ('ALGODEX_ALGOD_TOKEN' in process.env) ? process.env.ALGODEX_ALGOD_TOKEN : '', + PUBLIC_TEST_BACKEND_API: 'https://api-testnet-public.algodex.com/algodex-backend', + PUBLIC_TEST_INDEXER_SERVER: 'https://algoindexer.testnet.algoexplorerapi.io', + PUBLIC_TEST_INDEXER_PORT: '', + PUBLIC_TEST_INDEXER_TOKEN: '', + PUBLIC_TEST_ALGO_ORDERBOOK_APPID: 22045503, + PUBLIC_TEST_ASA_ORDERBOOK_APPID: 22045522, + + PROD_ALGOD_SERVER: ('ALGODEX_ALGOD_SERVER' in process.env) ? process.env.ALGODEX_ALGOD_SERVER : 'https://node.algoexplorerapi.io', + PROD_ALGOD_PORT: ('ALGODEX_ALGOD_PORT' in process.env) ? process.env.ALGODEX_ALGOD_PORT : '', + PROD_ALGOD_TOKEN: ('ALGODEX_ALGOD_TOKEN' in process.env) ? process.env.ALGODEX_ALGOD_TOKEN : '', + PROD_BACKEND_API: 'https://api.algodex.com/algodex-backend', + PROD_INDEXER_SERVER: 'https://algoindexer.algoexplorerapi.io', + PROD_INDEXER_PORT: '', + PROD_INDEXER_TOKEN: '', + PROD_ALGO_ORDERBOOK_APPID: 354073718, + PROD_ASA_ORDERBOOK_APPID: 354073834, +}; diff --git a/lib/order/__tests__/dex_teal.js b/lib/order/__tests__/dex_teal.js new file mode 100644 index 00000000..bfd9374f --- /dev/null +++ b/lib/order/__tests__/dex_teal.js @@ -0,0 +1,266 @@ +// /////////////////////////// +// Alexander Trefonas // +// 7/9/2021 // +// Copyright Algodev Inc // +// All Rights Reserved. // +// /////////////////////////// + +const AlgoOrderbookTeal = { + + + getClearProgram: function getClearProgram() { + const clearProgram = + ` +#pragma version 2 +// This program clears program state. +// This will clear local state for any escrow accounts that call this from a ClearState transaction, +// the logic of which is contained within the stateless contracts as part of a Close Out (Cancel Order) operation. +// We use ClearState instead of CloseOut so that the order book cannot prevent an escrow from closing out. +int 1 +` +; + return clearProgram; + }, + + getAlgoOrderBookApprovalProgram: function getAlgoOrderBookApprovalProgram() { + // stateful DEX contract + // This is for the order book + return ` +////////////////////////////////////////////////// +// STATEFUL CONTRACT / +// ORDER BOOK FOR ALGO ESCROWS (BUY ORDERS) / +////////////////////////////////////////////////// +#pragma version 4 + // STATEFUL APP CREATION + // check if the app is being created + // if so save creator + int 0 + txn ApplicationID // check if there is no application ID - means it hasn't been created + == + bz not_creation + byte "Creator" + txn Sender + app_global_put + int 1 + return + not_creation: + int DeleteApplication // check if this is deletion transaction + txn OnCompletion + == + bz not_deletion + byte "Creator" + app_global_get + txn Sender + == + assert + int 1 + return + not_deletion: + int UpdateApplication // check if this is update + txn OnCompletion + == + bz not_update + byte "Creator" // verify that the creator is making the call + app_global_get + txn Sender + == + assert + int 1 + return + not_update: + txna ApplicationArgs 0 + byte "open" + == + bnz open + txna ApplicationArgs 0 + byte "execute" + == + bnz execute + txna ApplicationArgs 0 + byte "execute_with_closeout" + == + bnz execute_with_closeout + err +/////////////////////////// +/// OPEN - ORDER BOOK OPT IN & REGISTRATION +// Placing an Algo Escrow Order +////////////////////////// + // TXN 0 - BUYER TO ESCROW: Pay from order creator to escrow account + // TXN 1 - ESCROW TO ORDERBOOK: Stateful app opt-in to order book + // TXN 2 - BUYER TO BUYER: (Optional) ASA opt-in for the order creator's original wallet account. + // This is the situation when a new escrow contract and order book contract is created + // These are for Algo-only escrow accounts, i.e. buy orders to buy ASAs + // The orders are unique per users + open: + gtxn 0 Amount // pay transaction must be over 1 algo + int 500000 // 0.5 algo. Also checked in the escrow contract + >= + assert + global GroupSize + int 2 + == + global GroupSize + int 3 + == + || + assert + int OptIn + txn OnCompletion + == + assert + int 0 //sender + txn ApplicationID //current smart contract + txna ApplicationArgs 1 // 2nd arg is order number + app_local_get_ex // if the value already exists return without setting anything + bnz ret_success + pop + int 0 //address index + txna ApplicationArgs 1 //order number + int 1 // value - just set to 1 + app_local_put // Store the order number as the key + int 0 //address index + byte "creator" //creator key + gtxn 0 Sender // The sender of the pay transaction + app_local_put // Store creator as value. + int 0 //address index. This is the Sender of this transaction. + byte "version" //store version + txna ApplicationArgs 2 //version + int 0 + getbyte + app_local_put // store the version + ret_success: + int 1 + return +/////////////////////////////////// +// EXECUTE +// (PARTIAL ORDER EXECUTION) +///////////////////////////////// + // TXN 0 - ESCROW TO ORDERBOOK: Transaction must be a call to a stateful contract + // TXN 1 - ESCROW TO SELLER: Payment transaction from this escrow to seller + // TXN 2 - SELLER TO BUYER: Asset transfer from seller to owner of this escrow (buyer) + // TXN 3 - SELLER TO ESCROW: Pay fee refund transaction + execute: + txn OnCompletion + int NoOp + == + assert + global GroupSize + int 4 + == + gtxn 0 TypeEnum // First Transaction must be a call to a stateful contract + int appl + == + && + gtxn 1 TypeEnum // The second transaction must be a payment transaction + int pay + == + && + gtxn 2 TypeEnum // The third transaction must be an asset transfer + int axfer + == + && + gtxn 3 TypeEnum // The fourth transaction must be a payment transaction to refund escrow fees + int pay + == + && + assert + txn Sender + balance + gtxn 1 Amount + - + int 499000 + >= // after subtracting the amount, over 0.499 algo must remain (0.5 - original txn fee from maker order) + assert + + int 0 // Escrow account containing order + txn ApplicationID // Current stateful smart contract + txna ApplicationArgs 1 // 2nd argument is order number + app_local_get_ex + assert // If the value doesnt exists fail + pop + int 0 // Escrow account containing order + txn ApplicationID // Current stateful smart contract + byte "creator" + app_local_get_ex // returns if it exists and the creator + assert // If the value doesnt exist fail + txna Accounts 1 // account arg is order creator + == + assert + global ZeroAddress + gtxn 1 CloseRemainderTo + == + assert + int 1 + return +/////////////////////////////// +// EXECUTE (ORDER EXECUTION) +// WITH CLOSEOUT +///////////////////////////////// + // TXN 0 - ESCROW TO ORDERBOOK: transaction must be a call to a stateful contract + // TXN 1 - ESCROW TO SELLER: Payment transaction from this escrow to seller, with closeout to owner (buyer) + // TXN 2 - SELLER TO BUYER: Asset transfer from seller to owner of this escrow (buyer) + execute_with_closeout: + txn Sender + balance + gtxn 1 Amount + - + int 500000 + < // after subtracting the amount, less than 0.5 algo must remain (to be closed out) + assert + txn OnCompletion + int CloseOut + == + global GroupSize // Must be three transactions + int 3 + == + && + gtxn 0 TypeEnum // First Transaction must be a call to a stateful contract + int appl + == + && + gtxn 1 TypeEnum // The second transaction must be a payment transaction + int pay + == + && + gtxn 2 TypeEnum // The third transaction must be an asset transfer + int axfer + == + && + assert + int 0 // Escrow account containing order + txn ApplicationID // Current stateful smart contract + txna ApplicationArgs 1 // 2nd argument is order number + app_local_get_ex + assert // If the value doesnt exists fail + pop + int 0 // Escrow account containing order + txn ApplicationID // Current stateful smart contract + byte "creator" + app_local_get_ex // returns if it exists and the creator + assert // If the value doesnt exist fail + txna Accounts 1 // account arg is order creator + == + assert + int 0 // Escrow account containing order + txn ApplicationID // Current stateful smart contract + byte "version" + app_local_get_ex + assert // If the value doesnt exists fail + pop + int 0 //escrow account containing order + txna ApplicationArgs 1 // order details + app_local_del // Delete the order details from the order book + int 0 + byte "creator" + app_local_del // Delete creator from order book + int 0 + byte "version" // Delete version from order book + app_local_del + int 1 + return + `; + }, +}; + +module.exports = AlgoOrderbookTeal; + diff --git a/lib/order/__tests__/generate_transaction_types.js b/lib/order/__tests__/generate_transaction_types.js new file mode 100644 index 00000000..bb5e74bd --- /dev/null +++ b/lib/order/__tests__/generate_transaction_types.js @@ -0,0 +1,988 @@ +/* eslint-disable */ + +const http = require('http'); +const algosdk = require('algosdk'); + +// const myAlgoWalletUtil = require('./MyAlgoWalletUtil.js'); +// const algoDelegateTemplate = require('./algo_delegate_template_teal.js'); +// const asaDelegateTemplate = require('./ASA_delegate_template_teal.js'); +const algoOrderBook = require('./dex_teal.js'); +const asaOrderBook = require('./asa_dex_teal.js'); + +// require('./dex_teal.js'); + +// const dexInternal = require('./algodex_internal_api.js'); +const algodex = require('./algodex_api.js'); + +const constants = require('./constants.js'); +const testHelper = require('./test_helper.js'); + +const ALGO_ESCROW_ORDER_BOOK_ID = -1; +const ASA_ESCROW_ORDER_BOOK_ID = -1; + +const GenerateTransactions = { + // helper function to compile program source + compileProgram: async function(client, programSource) { + const encoder = new TextEncoder(); + const programBytes = encoder.encode(programSource); + const compileResponse = await client.compile(programBytes).do(); + const compiledBytes = new Uint8Array( + Buffer.from(compileResponse.result, 'base64'), + ); + return compiledBytes; + }, + + getAssetSendTxn: async function( + client, + fromAcct, + toAcct, + amount, + assetId, + shouldClose, + ) { + if (typeof fromAcct !== 'string') { + fromAcct = fromAcct.addr; + } + if (typeof toAcct !== 'string') { + toAcct = toAcct.addr; + } + const params = await client.getTransactionParams().do(); + // comment out the next two lines to use suggested fee + params.fee = 1000; + params.flatFee = true; + let closeAddr = undefined; + if (shouldClose === true) { + closeAddr = toAcct; + } + + const txn = algosdk.makeAssetTransferTxnWithSuggestedParams( + fromAcct, + toAcct, + closeAddr, + undefined, + amount, + undefined, + assetId, + params, + ); + return txn; + }, + + getPayTxn: async function(client, fromAcct, toAcct, amount, shouldClose) { + if (typeof fromAcct !== 'string') { + fromAcct = fromAcct.addr; + } + if (typeof toAcct !== 'string') { + toAcct = toAcct.addr; + } + const params = await client.getTransactionParams().do(); + // comment out the next two lines to use suggested fee + params.fee = 1000; + params.flatFee = true; + const enc = new TextEncoder(); + const note = enc.encode('Hello World'); + let closeAddr = undefined; + if (shouldClose === true) { + closeAddr = toAcct; + } + const txn = algosdk.makePaymentTxnWithSuggestedParams( + fromAcct, + toAcct, + amount, + closeAddr, + note, + params, + ); + return txn; + }, + + getCreateAppTxn: async function( + client, + creatorAccount, + isAlgoEscrowApp = true, + ) { + // define sender as creator + let approvalProgramSource = null; + if (isAlgoEscrowApp) { + approvalProgramSource = algoOrderBook.getAlgoOrderBookApprovalProgram(); + } else { + approvalProgramSource = asaOrderBook.getASAOrderBookApprovalProgram(); + } + const clearProgramSource = algoOrderBook.getClearProgram(); + + // declare application state storage (immutable) + const localInts = 2; + const localBytes = 1; + const globalInts = 0; + const globalBytes = 1; + + sender = creatorAccount.addr; + + // declare onComplete as NoOp + onComplete = algosdk.OnApplicationComplete.NoOpOC; + + // get node suggested parameters + const params = await client.getTransactionParams().do(); + // create unsigned transaction + + const approvalProgram = await this.compileProgram( + client, + approvalProgramSource, + ); + const clearProgram = await this.compileProgram(client, clearProgramSource); + + const txn = algosdk.makeApplicationCreateTxn( + sender, + params, + onComplete, + approvalProgram, + clearProgram, + localInts, + localBytes, + globalInts, + globalBytes, + ); + + return txn; + }, + + getCloseAlgoEscrowOrderTxns: async function( + algodClient, + creator, + price, + assetId, + appId, + ) { + const numAndDenom = algodex.getNumeratorAndDenominatorFromPrice(price); + const n = numAndDenom.n; + const d = numAndDenom.d; + const creatorAddr = creator.addr; + + const escrowSource = algodex.buildDelegateTemplateFromArgs( + 0, + assetId, + n, + d, + creatorAddr, + false, + constants.ESCROW_CONTRACT_VERSION, + ); + const lsig = await algodex.getLsigFromProgramSource( + algosdk, + algodClient, + escrowSource, + constants.DEBUG_SMART_CONTRACT_SOURCE, + ); + const escrowAccountAddr = lsig.address(); + + const outerTxns = []; + // "2500-625-0-15322902" + const orderBookEntry = n + '-' + d + '-0-' + assetId; + console.log('closing order from order book entry!'); + console.log( + 'escrowAccountAddr, creatorAddr, orderBookEntry', + escrowAccountAddr, + creatorAddr, + orderBookEntry, + ); + + const appArgs = []; + const enc = new TextEncoder(); + appArgs.push(enc.encode('close')); + appArgs.push(enc.encode(orderBookEntry)); + // appArgs.push(enc.encode(creatorAddr)); + console.log('args length: ' + appArgs.length); + + // get node suggested parameters + const params = await algodClient.getTransactionParams().do(); + + // create unsigned transaction + const txn = algosdk.makeApplicationClearStateTxn( + lsig.address(), + params, + appId, + appArgs, + ); + outerTxns.push({ + unsignedTxn: txn, + lsig: lsig, + }); + // Submit the transaction + + // Make payment tx signed with lsig + const txn2 = algosdk.makePaymentTxnWithSuggestedParams( + lsig.address(), + creatorAddr, + 0, + creatorAddr, + undefined, + params, + ); + outerTxns.push({ + unsignedTxn: txn2, + lsig: lsig, + }); + + const txn3 = algosdk.makePaymentTxnWithSuggestedParams( + creatorAddr, + creatorAddr, + 0, + undefined, + undefined, + params, + ); + + outerTxns.push({ + unsignedTxn: txn3, + senderAcct: creator, + }); + + return outerTxns; + }, + + getCloseASAEscrowOrderTxns: async function( + algodClient, + creator, + price, + assetId, + appId, + ) { + const numAndDenom = algodex.getNumeratorAndDenominatorFromPrice(price); + const n = numAndDenom.n; + const d = numAndDenom.d; + const creatorAddr = creator.addr; + + const escrowSource = algodex.buildDelegateTemplateFromArgs( + 0, + assetId, + n, + d, + creatorAddr, + true, + constants.ESCROW_CONTRACT_VERSION, + ); + const lsig = await algodex.getLsigFromProgramSource( + algosdk, + algodClient, + escrowSource, + constants.DEBUG_SMART_CONTRACT_SOURCE, + ); + const escrowAccountAddr = lsig.address(); + + const outerTxns = []; + // "2500-625-0-15322902" + const orderBookEntry = n + '-' + d + '-0-' + assetId; + console.log('closing order from order book entry!'); + console.log( + 'escrowAccountAddr, creatorAddr, orderBookEntry', + escrowAccountAddr, + creatorAddr, + orderBookEntry, + ); + + const appArgs = []; + const enc = new TextEncoder(); + appArgs.push(enc.encode('close')); + appArgs.push(enc.encode(orderBookEntry)); + // appArgs.push(enc.encode(creatorAddr)); + console.log('args length: ' + appArgs.length); + + // get node suggested parameters + const params = await algodClient.getTransactionParams().do(); + + // create unsigned transaction + const txn = algosdk.makeApplicationClearStateTxn( + lsig.address(), + params, + appId, + appArgs, + ); + const txId = txn.txID().toString(); + // Submit the transaction + + // create optin transaction + // sender and receiver are both the same + const sender = lsig.address(); + const recipient = creatorAddr; + // We set revocationTarget to undefined as + // This is not a clawback operation + const revocationTarget = undefined; + // CloseReaminerTo is set to undefined as + // we are not closing out an asset + const closeRemainderTo = creatorAddr; + // We are sending 0 assets + const amount = 0; + + // signing and sending "txn" allows sender to begin accepting asset specified by creator and index + const txn2 = algosdk.makeAssetTransferTxnWithSuggestedParams( + sender, + recipient, + closeRemainderTo, + revocationTarget, + amount, + undefined, + assetId, + params, + ); + + // Make payment tx signed with lsig + const txn3 = algosdk.makePaymentTxnWithSuggestedParams( + lsig.address(), + creatorAddr, + 0, + creatorAddr, + undefined, + params, + ); + + // proof of ownership transaction + const txn4 = algosdk.makePaymentTxnWithSuggestedParams( + creatorAddr, + creatorAddr, + 0, + undefined, + undefined, + params, + ); + + outerTxns.push({ + unsignedTxn: txn, + lsig: lsig, + }); + outerTxns.push({ + unsignedTxn: txn2, + lsig: lsig, + }); + outerTxns.push({ + unsignedTxn: txn3, + lsig: lsig, + }); + outerTxns.push({ + unsignedTxn: txn4, + senderAcct: creator, + }); + + return outerTxns; + }, + + getExecuteAlgoEscrowOrderTxns: async function( + algodClient, + executorAccount, + makerAccount, + algoAmountReceiving, + asaAmountSending, + price, + assetId, + appId, + shouldClose = false, + ) { + const orderCreatorAddr = makerAccount.addr; + const min = 0; + const numAndDenom = algodex.getNumeratorAndDenominatorFromPrice(price); + const n = numAndDenom.n; + const d = numAndDenom.d; + const takerAddr = executorAccount.addr; + + let appCallType = null; + const orderBookEntry = algodex.generateOrder( + orderCreatorAddr, + n, + d, + min, + assetId, + false, + ); + const refundFees = 0.002 * 1000000; // fees refunded to escrow in case of partial execution + + const escrowSource = algodex.buildDelegateTemplateFromArgs( + 0, + assetId, + n, + d, + orderCreatorAddr, + false, + constants.ESCROW_CONTRACT_VERSION, + ); + const lsig = await algodex.getLsigFromProgramSource( + algosdk, + algodClient, + escrowSource, + constants.DEBUG_SMART_CONTRACT_SOURCE, + ); + const params = await algodClient.getTransactionParams().do(); + + const appAccts = []; + appAccts.push(orderCreatorAddr); + appAccts.push(takerAddr); + + let closeRemainderTo = undefined; + + if (shouldClose) { + closeRemainderTo = makerAccount.addr; + } + + if (closeRemainderTo == undefined) { + appCallType = 'execute'; + } else { + appCallType = 'execute_with_closeout'; + } + console.log('arg1: ' + appCallType); + console.log('arg2: ' + orderBookEntry); + console.log('arg3: ' + orderCreatorAddr); + + const appArgs = []; + const enc = new TextEncoder(); + appArgs.push(enc.encode(appCallType)); + appArgs.push(enc.encode(orderBookEntry)); + console.log(appArgs.length); + + let transaction1 = null; + + if (closeRemainderTo == undefined) { + transaction1 = algosdk.makeApplicationNoOpTxn( + lsig.address(), + params, + appId, + appArgs, + appAccts, + ); + } else { + transaction1 = algosdk.makeApplicationCloseOutTxn( + lsig.address(), + params, + appId, + appArgs, + appAccts, + ); + } + + // Make payment tx signed with lsig + const transaction2 = algosdk.makePaymentTxnWithSuggestedParams( + lsig.address(), + takerAddr, + algoAmountReceiving, + closeRemainderTo, + undefined, + params, + ); + // Make asset xfer + + const transaction3 = await this.getAssetSendTxn( + algodClient, + takerAddr, + orderCreatorAddr, + asaAmountSending, + assetId, + false, + ); + + let transaction4 = null; + + if (closeRemainderTo == undefined) { + // create refund transaction for fees + transaction4 = await this.getPayTxn( + algodClient, + takerAddr, + lsig.address(), + refundFees, + false, + ); + } + + const retTxns = []; + + retTxns.push({ + unsignedTxn: transaction1, + lsig: lsig, + }); + retTxns.push({ + unsignedTxn: transaction2, + lsig: lsig, + }); + retTxns.push({ + unsignedTxn: transaction3, + senderAcct: executorAccount, + }); + + if (transaction4 != null) { + retTxns.push({ + unsignedTxn: transaction4, + senderAcct: executorAccount, + }); + } + + return retTxns; + }, + + getExecuteASAEscrowOrderTxns: async function( + algodClient, + executorAccount, + makerAccount, + algoAmountSending, + asaAmountReceiving, + price, + assetId, + appId, + shouldClose = false, + ) { + console.log( + 'here664 ', + executorAccount, + makerAccount, + algoAmountSending, + asaAmountReceiving, + price, + assetId, + appId, + shouldClose, + ); + const orderCreatorAddr = makerAccount.addr; + const min = 0; + const numAndDenom = algodex.getNumeratorAndDenominatorFromPrice(price); + const n = numAndDenom.n; + const d = numAndDenom.d; + const takerAddr = executorAccount.addr; + + const refundFees = 0.002 * 1000000; // fees refunded to escrow in case of partial execution + + let appCallType = null; + const orderBookEntry = algodex.generateOrder( + orderCreatorAddr, + n, + d, + min, + assetId, + false, + ); + + const escrowSource = algodex.buildDelegateTemplateFromArgs( + 0, + assetId, + n, + d, + orderCreatorAddr, + true, + constants.ESCROW_CONTRACT_VERSION, + ); + const lsig = await algodex.getLsigFromProgramSource( + algosdk, + algodClient, + escrowSource, + constants.DEBUG_SMART_CONTRACT_SOURCE, + ); + const params = await algodClient.getTransactionParams().do(); + + const appAccts = []; + appAccts.push(orderCreatorAddr); + appAccts.push(takerAddr); + + let transaction1 = null; + let closeRemainderTo = undefined; + + if (shouldClose) { + closeRemainderTo = makerAccount.addr; + appCallType = 'execute_with_closeout'; + } else { + appCallType = 'execute'; + } + + const appArgs = []; + const enc = new TextEncoder(); + appArgs.push(enc.encode(appCallType)); + appArgs.push(enc.encode(orderBookEntry)); + + if (closeRemainderTo == undefined) { + transaction1 = algosdk.makeApplicationNoOpTxn( + lsig.address(), + params, + appId, + appArgs, + appAccts, + [0], + [assetId], + ); + } else { + transaction1 = algosdk.makeApplicationCloseOutTxn( + lsig.address(), + params, + appId, + appArgs, + appAccts, + [0], + [assetId], + ); + } + + console.log('app call type is: ' + appCallType); + + const transaction2 = await this.getPayTxn( + algodClient, + takerAddr, + orderCreatorAddr, + algoAmountSending, + false, + ); + + const accountInfo = await algodex.getAccountInfo(takerAddr); + let takerAlreadyOptedIntoASA = false; + if ( + accountInfo != null && + accountInfo['assets'] != null && + accountInfo['assets'].length > 0 + ) { + for (let i = 0; i < accountInfo['assets'].length; i++) { + if (accountInfo['assets'][i]['asset-id'] === assetId) { + takerAlreadyOptedIntoASA = true; + break; + } + } + } + + // asset opt-in transfer + let transaction2b = null; + + if (!takerAlreadyOptedIntoASA) { + transaction2b = await this.getAssetSendTxn( + algodClient, + takerAddr, + takerAddr, + 0, + assetId, + false, + ); + } + + // Make asset xfer + + // Asset transfer from escrow account to order executor + + const transaction3 = algosdk.makeAssetTransferTxnWithSuggestedParams( + lsig.address(), + takerAddr, + closeRemainderTo, + undefined, + asaAmountReceiving, + undefined, + assetId, + params, + ); + + let transaction4 = null; + if (closeRemainderTo != undefined) { + // Make payment tx signed with lsig back to owner creator + console.log('making transaction4 due to closeRemainderTo'); + transaction4 = algosdk.makePaymentTxnWithSuggestedParams( + lsig.address(), + orderCreatorAddr, + 0, + orderCreatorAddr, + undefined, + params, + ); + } else { + // Make fee refund transaction + transaction4 = await this.getPayTxn( + algodClient, + takerAddr, + lsig.address(), + refundFees, + false, + ); + } + + if (transaction2b != null) { + // myAlgoWalletUtil.setTransactionFee(transaction2b); + } + + const retTxns = []; + + retTxns.push({ + unsignedTxn: transaction1, + lsig: lsig, + }); + retTxns.push({ + unsignedTxn: transaction2, // FIXME - change to sdk + senderAcct: executorAccount, + }); + + if (transaction2b != null) { + retTxns.push({ + unsignedTxn: transaction2b, // FIXME - change to sdk + senderAcct: executorAccount, + }); + } + retTxns.push({ + unsignedTxn: transaction3, + lsig: lsig, + }); + if (closeRemainderTo != undefined) { + // close out algo balance to owner + retTxns.push({ + unsignedTxn: transaction4, + lsig: lsig, + }); + } else { + // fee refund + retTxns.push({ + unsignedTxn: transaction4, + senderAcct: executorAccount, + }); + } + + return retTxns; + }, + + getPlaceAlgoEscrowOrderTxns: async function( + algodClient, + makerAccount, + algoOrderSize, + price, + assetId, + appId, + isExistingEscrow = false, + skipASAOptIn = false, + ) { + const makerAddr = makerAccount.addr; + const min = 0; + const numAndDenom = algodex.getNumeratorAndDenominatorFromPrice(price); + const n = numAndDenom.n; + const d = numAndDenom.d; + console.log( + 'getPlaceAlgoEscrowOrderTxns makerWalletAddr, n, d, min, assetId', + makerAddr, + n, + d, + min, + assetId, + ); + const program = algodex.buildDelegateTemplateFromArgs( + min, + assetId, + n, + d, + makerAddr, + false, + constants.ESCROW_CONTRACT_VERSION, + ); + const lsig = await algodex.getLsigFromProgramSource( + algosdk, + algodClient, + program, + constants.DEBUG_SMART_CONTRACT_SOURCE, + ); + const generatedOrderEntry = algodex.generateOrder( + makerAddr, + n, + d, + min, + assetId, + ); + console.log('sending trans to: ' + lsig.address()); + + const txn = await this.getPayTxn( + algodClient, + makerAddr, + lsig.address(), + algoOrderSize, + false, + ); + const outerTxns = []; + + outerTxns.push({ + unsignedTxn: txn, + senderAcct: makerAccount, + }); + + console.log('here3 calling app from logic sig to open order'); + const appArgs = []; + const enc = new TextEncoder(); + appArgs.push(enc.encode('open')); + appArgs.push(enc.encode(generatedOrderEntry.slice(59))); + appArgs.push(new Uint8Array([constants.ESCROW_CONTRACT_VERSION])); + + // appArgs.push(algosdk.decodeAddress(makerAddr).publicKey); + + // console.log("owners bit addr: " + ownersBitAddr); + console.log('herezzz_888'); + console.log(appArgs.length); + const logSigTrans = null; + + if (!isExistingEscrow) { + // logSigTrans = await dexInternal.createTransactionFromLogicSig(algodClient, lsig, appId, appArgs, "appOptIn"); + // outerTxns.push({ + // unsignedTxn: logSigTrans, + // lsig: lsig + // }); + } + + console.log('skipASAOptIn: ' + skipASAOptIn); + + if (!skipASAOptIn) { + // asset opt-in transfer + const assetOptInTxn = await this.getAssetSendTxn( + algodClient, + makerAddr, + makerAddr, + 0, + assetId, + false, + ); + + outerTxns.push({ + unsignedTxn: assetOptInTxn, + senderAcct: makerAccount, + }); + } + return outerTxns; + }, + + getPlaceASAEscrowOrderTxns: async function( + algodClient, + makerAccount, + asaOrderSize, + price, + assetId, + appId, + isExistingEscrow = false, + ) { + console.log('checking assetId type'); + assetId = parseInt(assetId + ''); + + const makerAddr = makerAccount.addr; + const min = 0; + const numAndDenom = algodex.getNumeratorAndDenominatorFromPrice(price); + const n = numAndDenom.n; + const d = numAndDenom.d; + + const outerTxns = []; + + const program = algodex.buildDelegateTemplateFromArgs( + min, + assetId, + n, + d, + makerAddr, + true, + constants.ESCROW_CONTRACT_VERSION, + ); + + const lsig = await algodex.getLsigFromProgramSource( + algosdk, + algodClient, + program, + ); + const generatedOrderEntry = algodex.generateOrder( + makerAddr, + n, + d, + min, + assetId, + ); + console.log('address is: ' + lsig.address()); + + // check if the lsig has already opted in + const accountInfo = await algodex.getAccountInfo(lsig.address()); + let alreadyOptedIn = false; + if ( + accountInfo != null && + accountInfo['apps-local-state'] != null && + accountInfo['apps-local-state'].length > 0 && + accountInfo['apps-local-state'][0].id == appId + ) { + alreadyOptedIn = true; + } + console.log('alreadyOptedIn: ' + alreadyOptedIn); + console.log('acct info:' + JSON.stringify(accountInfo)); + + const params = await algodClient.getTransactionParams().do(); + console.log('sending trans to: ' + lsig.address()); + + const assetSendTrans = await this.getAssetSendTxn( + algodClient, + makerAddr, + lsig.address(), + asaOrderSize, + assetId, + false, + ); + + const payTxn = await this.getPayTxn( + algodClient, + makerAddr, + lsig.address(), + constants.MIN_ASA_ESCROW_BALANCE, + false, + ); + + // myAlgoWalletUtil.setTransactionFee(payTxn); + + console.log('typeof: ' + typeof payTxn.txId); + console.log('the val: ' + payTxn.txId); + + // console.log("confirmed!!"); + // create unsigned transaction + + console.log('here3 calling app from logic sig to open order'); + const appArgs = []; + const enc = new TextEncoder(); + appArgs.push(enc.encode('open')); + + appArgs.push(enc.encode(generatedOrderEntry.slice(59))); + appArgs.push(new Uint8Array([constants.ESCROW_CONTRACT_VERSION])); + + // add owners address as arg + // ownersAddr = "WYWRYK42XADLY3O62N52BOLT27DMPRA3WNBT2OBRT65N6OEZQWD4OSH6PI"; + // ownersBitAddr = (algosdk.decodeAddress(ownersAddr)).publicKey; + console.log(appArgs.length); + + // let logSigTrans = await dexInternal.createTransactionFromLogicSig(algodClient, lsig, appId, + // appArgs, "appOptIn"); + + // create optin transaction + // sender and receiver are both the same + const sender = lsig.address(); + const recipient = sender; + // We set revocationTarget to undefined as + // This is not a clawback operation + const revocationTarget = undefined; + // CloseReaminerTo is set to undefined as + // we are not closing out an asset + const closeRemainderTo = undefined; + // We are sending 0 assets + const amount = 0; + + // signing and sending "txn" allows sender to begin accepting asset specified by creator and index + const logSigAssetOptInTrans = + algosdk.makeAssetTransferTxnWithSuggestedParams( + sender, + recipient, + closeRemainderTo, + revocationTarget, + amount, + undefined, + assetId, + params, + ); + + outerTxns.push({ + unsignedTxn: payTxn, + senderAcct: makerAccount, + }); + outerTxns.push({ + unsignedTxn: logSigTrans, + lsig: lsig, + }); + outerTxns.push({ + unsignedTxn: logSigAssetOptInTrans, + lsig: lsig, + }); + outerTxns.push({ + unsignedTxn: assetSendTrans, + senderAcct: makerAccount, + }); + + return outerTxns; + }, +}; + +module.exports = GenerateTransactions; diff --git a/lib/order/__tests__/initCloseOrderAccounts.js b/lib/order/__tests__/initCloseOrderAccounts.js new file mode 100644 index 00000000..5c5d8ecc --- /dev/null +++ b/lib/order/__tests__/initCloseOrderAccounts.js @@ -0,0 +1,98 @@ +const {transferFunds, transferASA} = require('../../teal/utils'); +const {timeout} = require('../../../lib/teal/utils'); + +const AlgodexApi = require('../../AlgodexApi'); + +const tesnet = { + config: { + algod: { + uri: 'https://node.testnet.algoexplorerapi.io', + token: '', + }, + indexer: { + uri: 'https://algoindexer.testnet.algoexplorerapi.io', + token: '', + }, + explorer: { + uri: 'https://indexer.testnet.algoexplorerapi.io', + port: '', + }, + dexd: { + uri: 'https://api-testnet-public.algodex.com/algodex-backend', + token: '', + }, + }, +}; + +const algodexApi = new AlgodexApi(tesnet); + +/** + * + * @param {TestConfig} config + * @param {String} type + * @param {Object} amountPriceObject + * @return {Promise} + */ +async function initCloseOrderAccounts(config, type, {amount, price}) { + const {client, openAccount, creatorAccount, assetId} = config; + + await transferFunds(client, openAccount, creatorAccount, 2000000); // fund account for a place + await transferASA(client, creatorAccount, creatorAccount, 0, assetId); // optIn transaction + + if (type === 'sell') { + await transferASA(client, openAccount, creatorAccount, 2000000, assetId); // testASA + await timeout(7000); // give enough time for indexer to pick up asset + } + + const wallet = { + type: 'sdk', + address: config.creatorAccount.addr, + connector: { + ...config.connector, + sk: config.creatorAccount.sk, // Just in case we want to test signing and sending from the api and not from the tests. + connected: true, + }, + }; + algodexApi.setWallet(wallet); + + const sellOrder = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: config.creatorAccount.addr, + price: price, // Limit price for the asset + amount: amount, // Amount willing to purchase (The total amount sent will be price * amount) + execution: 'maker', + type: 'sell', + }; + + const buyOrder = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: config.creatorAccount.addr, + price: price, // Limit price for the asset + amount: amount, // Amount willing to purchase (The total amount sent will be price * amount) + execution: 'maker', + type: 'buy', + }; + + const result = await algodexApi.placeOrder(type === 'sell' ? sellOrder : buyOrder); + console.log(result); + + await timeout(7000); + return; + + // if (optIn) { + // await transferASA(client, executorAccount, executorAccount, 0, config.assetIndex); // opt in transaction + // await transferASA(client, openAccount, executorAccount, 2000000, config.assetIndex); // 5 algos + // } + + // await transferFunds(client, openAccount, maliciousAccount, 5000000); // 5 algos + // await transferASA(client, maliciousAccount, maliciousAccount, 0, config.assetIndex); // opt in transaction + // await transferASA(client, openAccount, maliciousAccount, 2000000, config.assetIndex); // 5 algos +} + +module.exports = initCloseOrderAccounts; diff --git a/lib/order/__tests__/setup.js b/lib/order/__tests__/setup.js new file mode 100644 index 00000000..c9cdd8ae --- /dev/null +++ b/lib/order/__tests__/setup.js @@ -0,0 +1,350 @@ +/* eslint-disable */ + +const http = require('http'); +const algosdk = require('algosdk'); +const axios = require('axios').default; +const signer = require('../../wallet/signers/AlgoSDK'); + +// const algoDelegateTemplate = require('./algo_delegate_template_teal.js'); +// const asaDelegateTemplate = require('./ASA_delegate_template_teal.js'); +// const algoOrderBook = require('./dex_teal.js'); +// const asaOrderBook = require('./asa_dex_teal.js'); + +// //require('./dex_teal.js'); +// const dexInternal = require('./algodex_internal_api.js'); +// const algodex = require('../../AlgodexApi.js'); +// TODO: need to replace this with v2. +// const constants = require('./constants.js'); +// const transactionGenerator = require('./generate_transaction_types.js'); + +// const ALGO_ESCROW_ORDER_BOOK_ID = -1; +// const ASA_ESCROW_ORDER_BOOK_ID = -1; + +const ALGOD_SERVER = 'https://node.testnet.algoexplorerapi.io'; +const ALGOD_TOKEN = ''; // { 'X-API-Key': 'VELyABA1dGqGbAVktbew4oACvp0c0298gMgYtYIb' } +const ALGOD_PORT = ''; + +const TestHelper = { + getLocalClient: function getLocalClientAndEnv() { + // const algodClient = algodex.initAlgodClient("test"); + const algodClient = new algosdk.Algodv2( + ALGOD_TOKEN, + ALGOD_SERVER, + ALGOD_PORT, + ); + return algodClient; + }, + + getRandomAccount: function getRandomAccount() { + return algosdk.generateAccount(); + }, + + getAccountInfo: async function getAccountInfo(addr) { + return algodex.getAccountInfo(addr); + + // This is the old account info that uses algod, not the indexer + // This is necessary for the tests to go faster as the indexer takes time to update. + + /* try { + let port = (!!ALGOD_PORT) ? ':' + ALGOD_PORT : ''; + const response = await axios.get(ALGOD_SERVER + port + "/v2/accounts/"+addr, {headers: {'X-Algo-API-Token': ALGOD_TOKEN}}); + //console.debug(response); + return response.data; + } catch (error) { + console.error(error); + throw new Error("getAccountInfo failed: ", error); + }*/ + }, + + printOuterTransactions: function(outerTxns) { + for (let i = 0; i < outerTxns.length; i++) { + console.log(outerTxns[i]); + } + }, + + checkFailureType: function(error) { + let hasKnownError = false; + + if (error != null && error.response.body.message != null) { + const msg = error.response.body.message; + if (msg.includes('rejected by logic err=')) { + hasKnownError = true; + } else if (msg.includes('TEAL runtime encountered err opcode')) { + hasKnownError = true; + } else { + throw 'Unknown error type: ' + msg; + } + } + + return hasKnownError; + }, + + getOpenAccount: function getOpenAccount() { + // WYWRYK42XADLY3O62N52BOLT27DMPRA3WNBT2OBRT65N6OEZQWD4OSH6PI + const mn = + 'mass army warrior number blush distance enroll vivid horse become spend asthma hat desert amazing room asset ivory lucky ridge now deputy erase absorb above'; + const openAccount = algosdk.mnemonicToSecretKey(mn); + return openAccount; + }, + + // transferASA: async function ( + // client, + // fromAccount, + // toAccount, + // amount, + // assetId + // ) { + // const asaTransferTxn = await transactionGenerator.getAssetSendTxn( + // client, + // fromAccount, + // toAccount, + // amount, + // assetId, + // false + // ); + // const asaTxnId = asaTransferTxn.txID().toString(); + + // const signedFundTxn = asaTransferTxn.signTxn(fromAccount.sk); + // console.log('Signed transaction with txID: %s', asaTxnId); + + // // Submit the transaction + // try { + // await client.sendRawTransaction(signedFundTxn).do(); + // } catch (e) { + // console.log(JSON.stringify(e)); + // } + + // // Wait for confirmation + // await this.checkPending(client, asaTxnId); + // }, + + // transferFunds: async function (client, fromAccount, toAccount, amount) { + // const fundTxn = await transactionGenerator.getPayTxn( + // client, + // fromAccount, + // toAccount, + // amount, + // false + // ); + // const fundTxnId = fundTxn.txID().toString(); + + // const signedFundTxn = fundTxn.signTxn(fromAccount.sk); + // console.log('Signed transaction with txID: %s', fundTxnId); + + // // Submit the transaction + // try { + // await client.sendRawTransaction(signedFundTxn).do(); + // } catch (e) { + // console.log(JSON.stringify(e)); + // } + + // // Wait for confirmation + // await this.checkPending(client, fundTxnId); + // }, + + // sendAndCheckConfirmed: async function (client, signedTxns) { + // // Submit the transaction + // let txId = null; + // try { + // const sentTxns = await client.sendRawTransaction(signedTxns).do(); + // txId = sentTxns.txId; + // } catch (e) { + // throw e; + // } + // // Wait for confirmation + // await this.waitForConfirmation(client, txId); + // }, + // sendAndCheckPending: async function (client, signedTxns) { + // // Submit the transaction + // let txId = null; + // try { + // const sentTxns = await client.sendRawTransaction(signedTxns).do(); + // txId = sentTxns.txId; + // } catch (e) { + // throw e; + // } + // // Wait for confirmation + // await this.checkPending(client, txId); + // }, + + // getAssetBalance: async function (accountAddr, assetId) { + // console.log('checking account info for: ' + accountAddr); + // const accountInfo = await this.getAccountInfo(accountAddr); + // if ( + // accountInfo != null && + // accountInfo['assets'] != null && + // accountInfo['assets'].length > 0 + // ) { + // for (let i = 0; i < accountInfo['assets'].length; i++) { + // const asset = accountInfo['assets'][i]; + // console.log({ asset }); + // if (asset['asset-id'] == assetId) { + // return asset['amount']; + // } + // } + // } + // return null; + // }, + + // closeAccount: async function closeAccount(client, fromAccount, toAccount) { + // console.log('checking account info for: ' + fromAccount.addr); + // const fromAccountInfo = await this.getAccountInfo(fromAccount.addr); + // if ( + // fromAccountInfo != null && + // fromAccountInfo['assets'] != null && + // fromAccountInfo['assets'].length > 0 + // ) { + // for (let i = 0; i < fromAccountInfo['assets'].length; i++) { + // const asset = fromAccountInfo['assets'][i]; + // const assetId = asset['asset-id']; + // console.log( + // 'closing asset: ' + assetId + ' for account: ' + fromAccount.addr + // ); + // const txn = await transactionGenerator.getAssetSendTxn( + // client, + // fromAccount, + // toAccount, + // 0, + // assetId, + // true + // ); + // const signedTxn = algosdk.signTransaction(txn, fromAccount.sk); + // await this.sendAndCheckPending(client, [signedTxn.blob]); + // } + // } + + // const fundTxn = await transactionGenerator.getPayTxn( + // client, + // fromAccount, + // toAccount, + // 0, + // true + // ); + // const fundTxnId = fundTxn.txID().toString(); + // const signedTxn = fundTxn.signTxn(fromAccount.sk); + // console.log('Signed transaction with txID: %s', fundTxnId); + // // Submit the transaction + // try { + // await client.sendRawTransaction(signedTxn).do(); + // } catch (e) { + // console.log(JSON.stringify(e)); + // } + // await this.checkPending(client, fundTxnId); + // }, + + // deleteApplication: async function deleteApplication(client, sender, appId) { + // // create unsigned transaction + // const params = await client.getTransactionParams().do(); + // const txn = algosdk.makeApplicationDeleteTxn(sender.addr, params, appId); + + // // sign, send, await + // const signedTxn = txn.signTxn(sender.sk); + // const txId = txn.txID().toString(); + + // console.log('Signed transaction with txID: %s', txId); + // // Submit the transaction + // try { + // await client.sendRawTransaction(signedTxn).do(); + // } catch (e) { + // console.log(JSON.stringify(e)); + // } + // // display results + // const transactionResponse = await client + // .pendingTransactionInformation(txId) + // .do(); + // console.log('Deleted app-id: ', appId); + // }, + + // getExecuteAccount: function getExecuteAccount() { + // // UUEUTRNQY7RUXESXRDO7HSYRSJJSSVKYVB4DI7X2HVVDWYOBWJOP5OSM3A + // const mn = + // 'three satisfy build purse lens another idle fashion base equal echo recall proof hill shadow coach early palm act wealth dawn menu portion above mystery'; + // const executeAccount = algosdk.mnemonicToSecretKey(mn); + // return executeAccount; + // }, + + // helper function to await transaction confirmation + // waitForConfirmation: async function waitForConfirmation(algodClient, txId) { + // const status = await algodClient.status().do(); + // let lastRound = status['last-round']; + // while (true) { + // const pendingInfo = await algodClient + // .pendingTransactionInformation(txId) + // .do(); + // if ( + // pendingInfo['confirmed-round'] !== null && + // pendingInfo['confirmed-round'] > 0 + // ) { + // // Got the completed Transaction + // console.log( + // 'Transaction ' + + // txId + + // ' confirmed in round ' + + // pendingInfo['confirmed-round'] + // ); + // break; + // } + // lastRound++; + // await algodClient.statusAfterBlock(lastRound).do(); + // } + // }, + + // helper function to await transaction confirmation + // checkPending: async function checkPending(algodClient, txId) { + // while (true) { + // const pendingInfo = await algodClient + // .pendingTransactionInformation(txId) + // .do(); + // if ( + // pendingInfo != null && + // pendingInfo.txn != null && + // pendingInfo.txn.txn != null + // ) { + // break; + // } + // } + // }, + + // groupAndSignTransactions: function (outerTxns) { + // console.log('inside signAndSend transactions'); + // const txns = []; + + // for (let i = 0; i < outerTxns.length; i++) { + // txns.push(outerTxns[i].unsignedTxn); + // } + + // const groupID = algosdk.computeGroupID(txns); + // for (let i = 0; i < txns.length; i++) { + // txns[i].group = groupID; + // } + + // for (let i = 0; i < outerTxns.length; i++) { + // const txn = outerTxns[i]; + // if (txn.lsig != null) { + // const signedLsig = algosdk.signLogicSigTransactionObject( + // txn.unsignedTxn, + // txn.lsig + // ); + // txn.signedTxn = signedLsig.blob; + // } else { + // const signedTxn = algosdk.signTransaction( + // txn.unsignedTxn, + // txn.senderAcct.sk + // ); + // txn.signedTxn = signedTxn.blob; + // } + // } + + // const signed = []; + + // for (let i = 0; i < outerTxns.length; i++) { + // signed.push(outerTxns[i].signedTxn); + // } + // console.log('printing transaction debug'); + // algodex.printTransactionDebug(signed); + + // return signed; + // }, +}; + +module.exports = TestHelper; diff --git a/lib/order/__tests__/takerAccountCleanup.js b/lib/order/__tests__/takerAccountCleanup.js new file mode 100644 index 00000000..82709e76 --- /dev/null +++ b/lib/order/__tests__/takerAccountCleanup.js @@ -0,0 +1,84 @@ +/* eslint-disable */ +const {transferFunds, transferASA} = require('../../teal/utils'); +/** + * + * @param {TestConfig} config + * @param {boolean} type + * @param {number} executorAmount + * @param {boolean} closeOut + * @return {Promise} + */ +async function takerAccountCleanup(config, type, executorAmount, closeOut) { + const { + client, + openAccount, + creatorAccount, + executorAccount, + assetId, + } = config; + + const executorAssetInformation = await config.client.accountAssetInformation(config.executorAccount.addr, config.assetId).do() + const creatorAssetInformation = await config.client.accountAssetInformation(config.creatorAccount.addr, config.assetId).do() + + if (type === 'sell') { + const formattedExecutorAmount = executorAmount * 1000000; + // escrowPlaceOrder + await transferASA( + client, + creatorAccount, + openAccount, + creatorAssetInformation["asset-holding"].amount, // initial 2 units less + assetId, + ); // transfer back ASA + await transferFunds(client, creatorAccount, openAccount, 1250000); // transfer original algo + + await transferASA( + client, + executorAccount, + openAccount, + executorAssetInformation["asset-holding"].amount, + assetId, + ); + await transferFunds(client, executorAccount, openAccount, 1250000); // transfer original algo + } + + if (type === 'buy') { + const formattedExecutorAmount = executorAmount * 1000000; + await transferASA( + client, + executorAccount, + openAccount, + executorAssetInformation["asset-holding"].amount, + assetId, + ); + await transferFunds(client, executorAccount, openAccount, 2000000); // transfer original algo + if (closeOut) { + await transferFunds(client, creatorAccount, openAccount, 1200000); + + + + await transferASA( + client, + creatorAccount, + openAccount, + creatorAssetInformation["asset-holding"].amount, + assetId, + ); + } else { + await transferFunds(client, creatorAccount, openAccount, 1500000); + await transferASA( + client, + creatorAccount, + openAccount, + creatorAssetInformation["asset-holding"].amount, + assetId, + ); + } + } + + // if (type === 'buy') { + // await transferFunds(client, creatorAccount, openAccount, 1750000); //transfer original algo + // } +} + +module.exports = takerAccountCleanup; diff --git a/lib/order/__tests__/takerSetup.js b/lib/order/__tests__/takerSetup.js new file mode 100644 index 00000000..68185432 --- /dev/null +++ b/lib/order/__tests__/takerSetup.js @@ -0,0 +1,78 @@ +/* eslint-disable */ +const {timeout} = require('../../../lib/teal/utils'); + +const AlgodexApi = require('../../AlgodexApi'); + +const tesnet = { + config: { + algod: { + uri: 'https://node.testnet.algoexplorerapi.io', + token: '', + }, + indexer: { + uri: 'https://algoindexer.testnet.algoexplorerapi.io', + token: '', + }, + explorer: { + uri: 'https://indexer.testnet.algoexplorerapi.io', + port: '', + }, + dexd: { + uri: 'https://api-testnet-public.algodex.com/algodex-backend', + token: '', + }, + }, +}; + +const algodexApi = new AlgodexApi(tesnet); + +/** + * + * @param {TestConfig} config + * @param {String} optIn + * @param {Object} newCreator + * @return {Promise} + */ +async function takerSetup(config, type, {amount, price}) { + const wallet = { + type: 'sdk', + address: config.openAccount.addr, + connector: { + ...config.connector, + sk: config.openAccount.sk, // Just in case we want to test signing and sending from the api and not from the tests. + connected: true, + }, + }; + algodexApi.setWallet(wallet); + + const sellOrder = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: config.openAccount.addr, + price: price, // Limit price for the asset + amount: amount, // Amount willing to purchase (The total amount sent will be price * amount) + execution: 'maker', + type: 'sell', + }; + + const buyOrder = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: config.openAccount.addr, + price: price, // Limit price for the asset + amount: amount, // Amount willing to purchase (The total amount sent will be price * amount) + execution: 'maker', + type: 'buy', + }; + + await algodexApi.placeOrder(type === 'sell' ? sellOrder : buyOrder); + + await timeout(7000); + return; +} + +module.exports = takerSetup; diff --git a/lib/order/__tests__/teal_tests/closeASAEscrowOrder.js b/lib/order/__tests__/teal_tests/closeASAEscrowOrder.js index 7d1aea27..c246cb6d 100644 --- a/lib/order/__tests__/teal_tests/closeASAEscrowOrder.js +++ b/lib/order/__tests__/teal_tests/closeASAEscrowOrder.js @@ -8,37 +8,77 @@ /* eslint-disable */ const testHelper = require('../setup.js'); -const transactionGenerator = require('../../lib/teal/generate_transaction_types.js'); +const transactionGenerator = require('../GenerateTransactionTypes'); const algosdk = require('algosdk'); +const signer = require('../../../wallet/signers/AlgoSDK'); +const _sendTransactions = require('./sendTransactions'); const PRINT_TXNS = 0; const Test = { - runTest: async function(config, price, returnOuterTransactions = false) { - console.log('STARTING close asa escrow order test'); + runTest: async function ( + config, + price, + asaAmount, + returnOuterTransactions = false + ) { + // console.log('STARTING close asa escrow order test'); + // const client = config.client; + // const creatorAccount = config.creatorAccount; + // const assetId = config.assetId; + // const appId = config.appId; + // console.log('creator account is: ' + creatorAccount.addr); + console.log('STARTING placeASAEscrowOrder test'); const client = config.client; - const creatorAccount = config.creatorAccount; - const assetId = config.assetId; - const appId = config.appId; - console.log('creator account is: ' + creatorAccount.addr); - const outerTxns = await transactionGenerator.getCloseASAEscrowOrderTxns(client, creatorAccount, price, assetId, appId); + const creatorAccount = config.creatorAccount.addr; + const wallet = { + type: 'sdk', + address: config.creatorAccount.addr, + connector: { + ...config.connector, + sk: config.creatorAccount.sk, //Just in case we want to test signing and sending from the api and not from the tests. + connected: true, + }, + // mnemonic: config.creatorAccount.sk, + }; + + const order = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: creatorAccount, + price: price, + amount: asaAmount, + total: price * asaAmount, + type: 'sell', + client: config.client, + execution: 'close', + wallet: wallet, + }; + + const closeASAEscrowOrder = + await transactionGenerator.getCloseASAEscrowOrderTxns(order); if (returnOuterTransactions) { return outerTxns; } - const signedTxns = testHelper.groupAndSignTransactions(outerTxns); + const signedTxns = await signer( + [closeASAEscrowOrder], + config.creatorAccount.sk + ); - await testHelper.sendAndCheckConfirmed(client, signedTxns); + const confirmation = await _sendTransactions(client, signedTxns); return true; }, - getOuterTransactions: async function(config) { + getOuterTransactions: async function (config) { const outerTxns = await this.runTest(config, 1.45, true); return outerTxns; }, - runGroupSizeWrongTest: async function(config) { + runGroupSizeWrongTest: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -49,9 +89,14 @@ const Test = { const lsig = outerTxns[0].lsig; - outerTxns.push( { - unsignedTxn: await transactionGenerator.getPayTxn(client, lsig.address(), maliciousAccount.addr, - 1000, false), + outerTxns.push({ + unsignedTxn: await transactionGenerator.getPayTxn( + client, + lsig.address(), + maliciousAccount.addr, + 1000, + false + ), lsig: lsig, }); @@ -66,7 +111,7 @@ const Test = { return false; }, - runGroupSizeWrongTest2: async function(config) { + runGroupSizeWrongTest2: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -77,9 +122,14 @@ const Test = { const lsig = outerTxns[0].lsig; - outerTxns.push( { - unsignedTxn: await transactionGenerator.getPayTxn(client, maliciousAccount.addr, maliciousAccount.addr, - 1000, false), + outerTxns.push({ + unsignedTxn: await transactionGenerator.getPayTxn( + client, + maliciousAccount.addr, + maliciousAccount.addr, + 1000, + false + ), senderAcct: maliciousAccount, }); @@ -94,7 +144,7 @@ const Test = { return false; }, - appCallMissing: async function(config) { + appCallMissing: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -104,8 +154,13 @@ const Test = { } outerTxns[0] = { - unsignedTxn: await transactionGenerator.getPayTxn(client, maliciousAccount.addr, maliciousAccount.addr, - 1000, false), + unsignedTxn: await transactionGenerator.getPayTxn( + client, + maliciousAccount.addr, + maliciousAccount.addr, + 1000, + false + ), senderAcct: maliciousAccount, }; @@ -120,7 +175,7 @@ const Test = { return false; }, - appCallMissing2: async function(config) { + appCallMissing2: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -142,7 +197,7 @@ const Test = { return false; }, - appCallWrongSender: async function(config) { + appCallWrongSender: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -151,7 +206,9 @@ const Test = { testHelper.printOuterTransactions(outerTxns); } - outerTxns[0].unsignedTxn.from = algosdk.decodeAddress(maliciousAccount.addr); + outerTxns[0].unsignedTxn.from = algosdk.decodeAddress( + maliciousAccount.addr + ); const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -164,7 +221,7 @@ const Test = { return false; }, - runASAWrongAddrCloseToTest: async function(config) { + runASAWrongAddrCloseToTest: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -173,7 +230,9 @@ const Test = { testHelper.printOuterTransactions(outerTxns); } - outerTxns[1].unsignedTxn.closeRemainderTo = algosdk.decodeAddress(maliciousAccount.addr); + outerTxns[1].unsignedTxn.closeRemainderTo = algosdk.decodeAddress( + maliciousAccount.addr + ); const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -186,7 +245,7 @@ const Test = { return false; }, - runAlgoWrongAddrCloseToTest: async function(config) { + runAlgoWrongAddrCloseToTest: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -195,7 +254,9 @@ const Test = { testHelper.printOuterTransactions(outerTxns); } - outerTxns[2].unsignedTxn.closeRemainderTo = algosdk.decodeAddress(maliciousAccount.addr); + outerTxns[2].unsignedTxn.closeRemainderTo = algosdk.decodeAddress( + maliciousAccount.addr + ); const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -208,7 +269,7 @@ const Test = { return false; }, - runASACloseToTxnHasNonZeroAmount: async function(config) { + runASACloseToTxnHasNonZeroAmount: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -230,7 +291,7 @@ const Test = { return false; }, - runAlgoCloseToTxnHasNonZeroAmount: async function(config) { + runAlgoCloseToTxnHasNonZeroAmount: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -252,7 +313,7 @@ const Test = { return false; }, - runWrongOwnerProofTest: async function(config) { + runWrongOwnerProofTest: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -261,7 +322,9 @@ const Test = { testHelper.printOuterTransactions(outerTxns); } - outerTxns[3].unsignedTxn.from = algosdk.decodeAddress(maliciousAccount.addr); + outerTxns[3].unsignedTxn.from = algosdk.decodeAddress( + maliciousAccount.addr + ); const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -273,6 +336,5 @@ const Test = { return false; }, - }; module.exports = Test; diff --git a/lib/order/__tests__/teal_tests/closeAlgoEscrowOrder.js b/lib/order/__tests__/teal_tests/closeAlgoEscrowOrder.js index cda239e5..a231b36b 100644 --- a/lib/order/__tests__/teal_tests/closeAlgoEscrowOrder.js +++ b/lib/order/__tests__/teal_tests/closeAlgoEscrowOrder.js @@ -8,37 +8,71 @@ /* eslint-disable */ const testHelper = require('../setup.js'); -const transactionGenerator = require('../../lib/teal/generate_transaction_types.js'); +const transactionGenerator = require('../GenerateTransactionTypes'); const algosdk = require('algosdk'); +const signer = require('../../../wallet/signers/AlgoSDK'); +const _sendTransactions = require('./sendTransactions'); const PRINT_TXNS = 0; const Test = { - runTest: async function(config, price, returnOuterTransactions = false) { - console.log('STARTING close algo escrow order test'); + runTest: async function ( + config, + price, + asaAmount, + returnOuterTransactions = false + ) { + console.log('STARTING placeASAEscrowOrder test'); const client = config.client; - const creatorAccount = config.creatorAccount; - const assetId = config.assetId; - const appId = config.appId; - console.log('creator account is: ' + creatorAccount.addr); - const outerTxns = await transactionGenerator.getCloseAlgoEscrowOrderTxns(client, creatorAccount, price, assetId, appId); + const creatorAccount = config.creatorAccount.addr; + const wallet = { + type: 'sdk', + address: config.creatorAccount.addr, + connector: { + ...config.connector, + sk: config.creatorAccount.sk, //Just in case we want to test signing and sending from the api and not from the tests. + connected: true, + }, + // mnemonic: config.creatorAccount.sk, + }; + + const order = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: creatorAccount, + price: price, + amount: asaAmount, + total: price * asaAmount, + type: 'buy', + client: config.client, + execution: 'close', + wallet: wallet, + }; + + const closeAlgoEscrowOrder = + await transactionGenerator.getCloseAlgoEscrowOrderTxns(order); if (returnOuterTransactions) { return outerTxns; } - const signedTxns = testHelper.groupAndSignTransactions(outerTxns); + const signedTxns = await signer( + [closeAlgoEscrowOrder], + config.creatorAccount.sk + ); - await testHelper.sendAndCheckConfirmed(client, signedTxns); + const confirmation = await _sendTransactions(client, signedTxns); return true; }, - getOuterTransactions: async function(config) { + getOuterTransactions: async function (config) { const outerTxns = await this.runTest(config, 1.2, true); return outerTxns; }, - runGroupSizeWrongTest: async function(config) { + runGroupSizeWrongTest: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -49,9 +83,14 @@ const Test = { const lsig = outerTxns[0].lsig; - outerTxns.push( { - unsignedTxn: await transactionGenerator.getPayTxn(client, lsig.address(), maliciousAccount.addr, - 1000, false), + outerTxns.push({ + unsignedTxn: await transactionGenerator.getPayTxn( + client, + lsig.address(), + maliciousAccount.addr, + 1000, + false + ), lsig: lsig, }); @@ -66,7 +105,7 @@ const Test = { return false; }, - runGroupSizeWrongTest2: async function(config) { + runGroupSizeWrongTest2: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -77,9 +116,14 @@ const Test = { const lsig = outerTxns[0].lsig; - outerTxns.push( { - unsignedTxn: await transactionGenerator.getPayTxn(client, maliciousAccount.addr, maliciousAccount.addr, - 1000, false), + outerTxns.push({ + unsignedTxn: await transactionGenerator.getPayTxn( + client, + maliciousAccount.addr, + maliciousAccount.addr, + 1000, + false + ), senderAcct: maliciousAccount, }); @@ -94,7 +138,7 @@ const Test = { return false; }, - runAlgoWrongAddrCloseToTest: async function(config) { + runAlgoWrongAddrCloseToTest: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -103,7 +147,9 @@ const Test = { testHelper.printOuterTransactions(outerTxns); } - outerTxns[1].unsignedTxn.closeRemainderTo = algosdk.decodeAddress(maliciousAccount.addr); + outerTxns[1].unsignedTxn.closeRemainderTo = algosdk.decodeAddress( + maliciousAccount.addr + ); const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -116,7 +162,7 @@ const Test = { return false; }, - runCloseToTxnHasNonZeroAmount: async function(config) { + runCloseToTxnHasNonZeroAmount: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -138,7 +184,7 @@ const Test = { return false; }, - runAlgoWrongOwnerProofTest: async function(config) { + runAlgoWrongOwnerProofTest: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -147,7 +193,9 @@ const Test = { testHelper.printOuterTransactions(outerTxns); } - outerTxns[2].unsignedTxn.from = algosdk.decodeAddress(maliciousAccount.addr); + outerTxns[2].unsignedTxn.from = algosdk.decodeAddress( + maliciousAccount.addr + ); const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -160,7 +208,7 @@ const Test = { return false; }, - appCallMissing: async function(config) { + appCallMissing: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -170,8 +218,13 @@ const Test = { } outerTxns[0] = { - unsignedTxn: await transactionGenerator.getPayTxn(client, maliciousAccount.addr, maliciousAccount.addr, - 1000, false), + unsignedTxn: await transactionGenerator.getPayTxn( + client, + maliciousAccount.addr, + maliciousAccount.addr, + 1000, + false + ), senderAcct: maliciousAccount, }; @@ -186,7 +239,7 @@ const Test = { return false; }, - payTxnWrongType: async function(config) { + payTxnWrongType: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -196,8 +249,13 @@ const Test = { } outerTxns[1] = { - unsignedTxn: await transactionGenerator.getPayTxn(client, maliciousAccount.addr, maliciousAccount.addr, - 1000, false), + unsignedTxn: await transactionGenerator.getPayTxn( + client, + maliciousAccount.addr, + maliciousAccount.addr, + 1000, + false + ), senderAcct: maliciousAccount, }; @@ -212,7 +270,7 @@ const Test = { return false; }, - refundTxnWrongType: async function(config) { + refundTxnWrongType: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -222,8 +280,13 @@ const Test = { } outerTxns[2] = { - unsignedTxn: await transactionGenerator.getPayTxn(client, maliciousAccount.addr, maliciousAccount.addr, - 1000, false), + unsignedTxn: await transactionGenerator.getPayTxn( + client, + maliciousAccount.addr, + maliciousAccount.addr, + 1000, + false + ), senderAcct: maliciousAccount, }; diff --git a/lib/order/__tests__/teal_tests/createAppTest.js b/lib/order/__tests__/teal_tests/createAppTest.js new file mode 100644 index 00000000..427f8f5a --- /dev/null +++ b/lib/order/__tests__/teal_tests/createAppTest.js @@ -0,0 +1,61 @@ +/* eslint-disable */ + +const testHelper = require('../setup.js'); +const transactionGenerator = require('../generate_transaction_types.js'); +const algosdk = require('algosdk'); + +const Test = { + runTest: createAppTest = async (config, isAlgoEscrowApp = true, optIntoASAForExecutor = true) => { + console.log('STARTING createAppTest: ', {isAlgoEscrowApp} ); + const client = config.client; + const openAccount = config.openAccount; + const maliciousAccount = config.maliciousAccount; + const creatorAccount = config.creatorAccount; + const executorAccount = config.executorAccount; + + console.log('starting the test'); + + await testHelper.transferFunds(client, openAccount, creatorAccount, 5000000); // 5 algos + await testHelper.transferFunds(client, openAccount, executorAccount, 5000000); // 5 algos + await testHelper.transferASA(client, creatorAccount, creatorAccount, 0, config.assetId); // opt in transaction + await testHelper.transferASA(client, openAccount, creatorAccount, 2000000, config.assetId); // 5 algos + if (optIntoASAForExecutor) { + await testHelper.transferASA(client, executorAccount, executorAccount, 0, config.assetId); // opt in transaction + await testHelper.transferASA(client, openAccount, executorAccount, 2000000, config.assetId); // 5 algos + } + + await testHelper.transferFunds(client, openAccount, maliciousAccount, 5000000); // 5 algos + await testHelper.transferASA(client, maliciousAccount, maliciousAccount, 0, config.assetId); // opt in transaction + await testHelper.transferASA(client, openAccount, maliciousAccount, 2000000, config.assetId); // 5 algos + + const createTxn = await transactionGenerator.getCreateAppTxn(client, creatorAccount, isAlgoEscrowApp); + const txId = createTxn.txID().toString(); + console.log('txID: ' + txId); + + // Sign the transaction + + const signedTxn = createTxn.signTxn(creatorAccount.sk); + console.log('Signed transaction with txID: %s', txId); + + // Submit the transaction + try { + await client.sendRawTransaction(signedTxn).do(); + } catch (e) { + console.log(JSON.stringify(e)); + } + + // Wait for confirmation + await testHelper.waitForConfirmation(client, txId); + + // display results + const transactionResponse = await client.pendingTransactionInformation(txId).do(); + appId = transactionResponse['application-index']; + console.log('Created new app-id: ', appId); + + const accountInfo = await testHelper.getAccountInfo(creatorAccount.addr); + console.log( 'amount: ', accountInfo.amount ); + + return appId; + }, +}; +module.exports = Test; diff --git a/lib/order/__tests__/teal_tests/executeASAEscrowOrder.js b/lib/order/__tests__/teal_tests/executeASAEscrowOrder.js index b2b1c739..552576b0 100644 --- a/lib/order/__tests__/teal_tests/executeASAEscrowOrder.js +++ b/lib/order/__tests__/teal_tests/executeASAEscrowOrder.js @@ -8,38 +8,125 @@ /* eslint-disable */ const testHelper = require('../setup.js'); -const transactionGenerator = require('../../lib/teal/generate_transaction_types.js'); +const transactionGenerator = require('../GenerateTransactionTypes'); const algosdk = require('algosdk'); +const signer = require('../../../wallet/signers/AlgoSDK'); +const _sendTransactions = require('./sendTransactions'); +const withExecuteTxns = require('../../structure/taker/withExecuteTxns') +const compile = require('../../compile/compile') const PRINT_TXNS = 0; + const Test = { - runPartialExecTest: async function(config, asaAmountReceiving, price, returnOuterTransactions = false) { - console.log('STARTING executeASAEscrowOrder partial test'); + runTest: async function ( + config, + takerAmount, + price, + returnOuterTransactions = false + ) { + const client = config.client; - const executorAccount = config.executorAccount; - const creatorAccount = config.creatorAccount; - const appId = config.appId; - let algoAmountSending = asaAmountReceiving * price; + const creatorAccount = config.executorAccount.addr; + const wallet = { + type: 'sdk', + address: config.executorAccount.addr, + connector: { + ...config.connector, + sk: config.creatorAccount.sk, //Just in case we want to test signing and sending from the api and not from the tests. + connected: true, + }, + // mnemonic: config.creatorAccount.sk, + }; + + const order = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: config.executorAccount.addr, + price: price, + amount: takerAmount, + total: price * takerAmount, + type: 'buy', + client: config.client, + execution: 'taker', + wallet: wallet, + }; + + const executePartialASAEscrowOrder = + await transactionGenerator.getTakerOrderTxns(order); - if (Math.floor(algoAmountSending) != algoAmountSending) { - algoAmountSending = Math.floor(algoAmountSending) + 1; // give slightly better deal to maker + if (returnOuterTransactions) { + return outerTxns; } + const signedTxns = await signer( + executePartialASAEscrowOrder, + config.executorAccount.sk + ); - const outerTxns = await transactionGenerator.getExecuteASAEscrowOrderTxns(client, executorAccount, creatorAccount, - algoAmountSending, asaAmountReceiving, price, config.assetId, appId, false); + const confirmation = await _sendTransactions(client, signedTxns); + + return true; + }, + runCloseOutExecutionTest: async function ( + config, + takerAmount, + price, + returnOuterTransactions = false + ) { + console.log('STARTING runPartialExecTest'); + const client = config.client; + + const creatorAccount = config.executorAccount.addr; + const wallet = { + type: 'sdk', + address: config.executorAccount.addr, + connector: { + ...config.connector, + sk: config.creatorAccount.sk, //Just in case we want to test signing and sending from the api and not from the tests. + connected: true, + }, + // mnemonic: config.creatorAccount.sk, + }; + + const order = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: config.executorAccount.addr, + price: price, + amount: takerAmount, + total: price * takerAmount, + type: 'buy', + client: config.client, + execution: 'execute', + wallet: wallet, + appId: 22045522, + version: 6, + }; + + const executeCloseOutASAEscrowOrder = + await withExecuteTxns(await compile(order), true) if (returnOuterTransactions) { return outerTxns; } + const signedTxns = await signer( + executeCloseOutASAEscrowOrder, + config.executorAccount.sk + ); - const signedTxns = testHelper.groupAndSignTransactions(outerTxns); - - await testHelper.sendAndCheckConfirmed(client, signedTxns); + const confirmation = await _sendTransactions(client, signedTxns); return true; }, - runFullExecTest: async function(config, price, returnOuterTransactions = false) { + runFullExecTest: async function ( + config, + price, + returnOuterTransactions = false + ) { console.log('STARTING executeASAEscrowOrder full test'); const client = config.client; const executorAccount = config.executorAccount; @@ -47,9 +134,18 @@ const Test = { const appId = config.appId; const assetId = config.assetId; - const lsig = await testHelper.getOrderLsig(client, creatorAccount, price, config.assetId, true); + const lsig = await testHelper.getOrderLsig( + client, + creatorAccount, + price, + config.assetId, + true + ); - const asaAmountReceiving = await testHelper.getAssetBalance(lsig.address(), assetId); + const asaAmountReceiving = await testHelper.getAssetBalance( + lsig.address(), + assetId + ); let algoAmountSending = asaAmountReceiving * price; @@ -57,9 +153,18 @@ const Test = { algoAmountSending = Math.floor(algoAmountSending) + 1; // give slightly better deal to maker } - console.log({asaAmountReceiving}, {algoAmountSending}); - const outerTxns = await transactionGenerator.getExecuteASAEscrowOrderTxns(client, executorAccount, creatorAccount, - algoAmountSending, asaAmountReceiving, price, assetId, appId, true); + console.log({ asaAmountReceiving }, { algoAmountSending }); + const outerTxns = await transactionGenerator.getExecuteASAEscrowOrderTxns( + client, + config.executorAccount, + creatorAccount, + algoAmountSending, + asaAmountReceiving, + price, + assetId, + appId, + true + ); if (returnOuterTransactions) { return outerTxns; @@ -70,15 +175,21 @@ const Test = { return true; }, - getOuterExecTransations: async function(config, useFullOrderExecution) { + getOuterExecTransations: async function (config, useFullOrderExecution) { if (useFullOrderExecution) { return await this.runFullExecTest(config, 1.25, true); } return await this.runPartialExecTest(config, 200000, 1.25, true); }, - runAssetAmtTooLargeTest: async function(config, useFullOrderExecution = true) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runAssetAmtTooLargeTest: async function ( + config, + useFullOrderExecution = true + ) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; if (PRINT_TXNS) { @@ -98,8 +209,14 @@ const Test = { return false; }, - runAlgoAmtTooSmallTest: async function(config, useFullOrderExecution = true) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runAlgoAmtTooSmallTest: async function ( + config, + useFullOrderExecution = true + ) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; if (PRINT_TXNS) { @@ -119,8 +236,11 @@ const Test = { return false; }, - runGroupSizeWrongTest: async function(config, useFullOrderExecution = true) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runGroupSizeWrongTest: async function (config, useFullOrderExecution = true) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -130,9 +250,14 @@ const Test = { const lsig = outerTxns[0].lsig; - outerTxns.push( { - unsignedTxn: await transactionGenerator.getPayTxn(client, lsig.address(), maliciousAccount.addr, - 1000, false), + outerTxns.push({ + unsignedTxn: await transactionGenerator.getPayTxn( + client, + lsig.address(), + maliciousAccount.addr, + 1000, + false + ), lsig: lsig, }); @@ -147,8 +272,14 @@ const Test = { return false; }, - runGroupSizeWrongTest2: async function(config, useFullOrderExecution = true) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runGroupSizeWrongTest2: async function ( + config, + useFullOrderExecution = true + ) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -158,9 +289,14 @@ const Test = { const lsig = outerTxns[0].lsig; - outerTxns.push( { - unsignedTxn: await transactionGenerator.getPayTxn(client, maliciousAccount.addr, maliciousAccount.addr, - 1000, false), + outerTxns.push({ + unsignedTxn: await transactionGenerator.getPayTxn( + client, + maliciousAccount.addr, + maliciousAccount.addr, + 1000, + false + ), senderAcct: maliciousAccount, }); @@ -175,8 +311,14 @@ const Test = { return false; }, - runAlgoAmtWrongAddrTest: async function(config, useFullOrderExecution = true) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runAlgoAmtWrongAddrTest: async function ( + config, + useFullOrderExecution = true + ) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -197,8 +339,14 @@ const Test = { return false; }, - runASAWrongAddrCloseToTest: async function(config, useFullOrderExecution = true) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runASAWrongAddrCloseToTest: async function ( + config, + useFullOrderExecution = true + ) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -209,7 +357,8 @@ const Test = { // check for optInTxn const optInOffset = outerTxns.length == 5 ? 1 : 0; - outerTxns[2+optInOffset].unsignedTxn.closeRemainderTo = algosdk.decodeAddress(maliciousAccount.addr); + outerTxns[2 + optInOffset].unsignedTxn.closeRemainderTo = + algosdk.decodeAddress(maliciousAccount.addr); const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -222,8 +371,14 @@ const Test = { return false; }, - runFeeToWrongAddrTest: async function(config, useFullOrderExecution = false) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runFeeToWrongAddrTest: async function ( + config, + useFullOrderExecution = false + ) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -234,7 +389,9 @@ const Test = { // check for optInTxn const optInOffset = outerTxns.length == 5 ? 1 : 0; - outerTxns[3+optInOffset].unsignedTxn.to = algosdk.decodeAddress(maliciousAccount.addr); + outerTxns[3 + optInOffset].unsignedTxn.to = algosdk.decodeAddress( + maliciousAccount.addr + ); const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -247,8 +404,11 @@ const Test = { return false; }, - runFeeTooSmallTest: async function(config, useFullOrderExecution = false) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runFeeTooSmallTest: async function (config, useFullOrderExecution = false) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -259,7 +419,7 @@ const Test = { // check for optInTxn const optInOffset = outerTxns.length == 5 ? 1 : 0; - outerTxns[3+optInOffset].unsignedTxn.amount = 1000; + outerTxns[3 + optInOffset].unsignedTxn.amount = 1000; const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -272,8 +432,14 @@ const Test = { return false; }, - runFeeFromWrongAddrTest: async function(config, useFullOrderExecution = false) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runFeeFromWrongAddrTest: async function ( + config, + useFullOrderExecution = false + ) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; console.log('inside runFeeFromWrongAddrTest'); @@ -285,9 +451,16 @@ const Test = { const optInOffset = outerTxns.length == 5 ? 1 : 0; const lsig = outerTxns[0].lsig; - outerTxns[3+optInOffset].unsignedTxn = await transactionGenerator.getPayTxn(client, lsig.address(), lsig.address(), 2000, false); - outerTxns[3+optInOffset].lsig = lsig; - outerTxns[3+optInOffset].senderAcct = null; + outerTxns[3 + optInOffset].unsignedTxn = + await transactionGenerator.getPayTxn( + client, + lsig.address(), + lsig.address(), + 2000, + false + ); + outerTxns[3 + optInOffset].lsig = lsig; + outerTxns[3 + optInOffset].senderAcct = null; const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -300,8 +473,14 @@ const Test = { return false; }, - runAppCallWrongAppTest: async function(config, useFullOrderExecution = false) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runAppCallWrongAppTest: async function ( + config, + useFullOrderExecution = false + ) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; console.log('inside runFeeFromWrongAddrTest'); @@ -322,9 +501,15 @@ const Test = { return false; }, - runAlgoBalanceCloseoutToWrongAddressTest: async function(config, useFullOrderExecution = false) { + runAlgoBalanceCloseoutToWrongAddressTest: async function ( + config, + useFullOrderExecution = false + ) { console.log('in runAlgoBalanceCloseoutToWrongAddressTest'); - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -335,8 +520,9 @@ const Test = { // check for optInTxn const optInOffset = outerTxns.length == 5 ? 1 : 0; - outerTxns[3+optInOffset].unsignedTxn.closeRemainderTo = algosdk.decodeAddress(maliciousAccount.addr); - console.log({outerTxns}); + outerTxns[3 + optInOffset].unsignedTxn.closeRemainderTo = + algosdk.decodeAddress(maliciousAccount.addr); + console.log({ outerTxns }); const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -349,8 +535,14 @@ const Test = { return false; }, - runAlgoPayAmountNotZeroTest: async function(config, useFullOrderExecution = false) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runAlgoPayAmountNotZeroTest: async function ( + config, + useFullOrderExecution = false + ) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -361,7 +553,7 @@ const Test = { // check for optInTxn const optInOffset = outerTxns.length == 5 ? 1 : 0; - outerTxns[3+optInOffset].unsignedTxn.amount = 1000; + outerTxns[3 + optInOffset].unsignedTxn.amount = 1000; const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -374,8 +566,14 @@ const Test = { return false; }, - runWrongTransactionTypeTest: async function(config, useFullOrderExecution = false) { - const outerTxns = await this.getOuterExecTransations(config, useFullOrderExecution); + runWrongTransactionTypeTest: async function ( + config, + useFullOrderExecution = false + ) { + const outerTxns = await this.getOuterExecTransations( + config, + useFullOrderExecution + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -387,10 +585,17 @@ const Test = { const optInOffset = outerTxns.length == 5 ? 1 : 0; const lsig = outerTxns[0].lsig; - outerTxns[3+optInOffset].unsignedTxn = await transactionGenerator.getAssetSendTxn(client, lsig.address(), maliciousAccount.addr, 2000, - config.assetId, false); - outerTxns[3+optInOffset].lsig = lsig; - outerTxns[3+optInOffset].senderAcct = null; + outerTxns[3 + optInOffset].unsignedTxn = + await transactionGenerator.getAssetSendTxn( + client, + lsig.address(), + maliciousAccount.addr, + 2000, + config.assetId, + false + ); + outerTxns[3 + optInOffset].lsig = lsig; + outerTxns[3 + optInOffset].senderAcct = null; const signedTxns = testHelper.groupAndSignTransactions(outerTxns); try { @@ -402,7 +607,5 @@ const Test = { return false; }, - - }; module.exports = Test; diff --git a/lib/order/__tests__/teal_tests/executeAlgoEscrowOrder.js b/lib/order/__tests__/teal_tests/executeAlgoEscrowOrder.js index f5fa7843..e4f23e61 100644 --- a/lib/order/__tests__/teal_tests/executeAlgoEscrowOrder.js +++ b/lib/order/__tests__/teal_tests/executeAlgoEscrowOrder.js @@ -6,73 +6,65 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +/* eslint-disable */ /* eslint-disable */ const testHelper = require('../setup.js'); -const transactionGenerator = require('../../lib/teal/generate_transaction_types.js'); +const transactionGenerator = require('../GenerateTransactionTypes'); const algosdk = require('algosdk'); -const {printTransactionDebug} = require('../../lib/functions/base.js'); +const signer = require('../../../wallet/signers/AlgoSDK'); +const _sendTransactions = require('./sendTransactions'); const PRINT_TXNS = 0; const Test = { - runPartialExecTest: async function(config, returnOuterTransactions = false) { - console.log('STARTING executeAlgoEscrowOrder runPartialExecTest test'); - const client = config.client; - const executorAccount = config.executorAccount; - const creatorAccount = config.creatorAccount; - const appId = config.appId; - - const algoAmountReceiving = 130000; - const price = 1.2; - - let asaAmountSending = algoAmountReceiving / price; - if (Math.floor(asaAmountSending) != asaAmountSending) { - asaAmountSending = Math.floor(asaAmountSending) + 1; // give slightly better deal to maker - } - - const outerTxns = await transactionGenerator.getExecuteAlgoEscrowOrderTxns(client, executorAccount, creatorAccount, - algoAmountReceiving, asaAmountSending, price, config.assetId, appId, false); - - if (returnOuterTransactions) { - return outerTxns; - } - - const signedTxns = testHelper.groupAndSignTransactions(outerTxns); - - await testHelper.sendAndCheckConfirmed(client, signedTxns); - - return true; - }, - - runFullExecTest: async function(config, returnOuterTransactions = false) { - console.log('STARTING executeAlgoEscrowOrder runFullExecTest test'); + runTest: async function( + config, + takerAmount, + price, + returnOuterTransactions = false) { const client = config.client; - const executorAccount = config.executorAccount; - const creatorAccount = config.creatorAccount; - const appId = config.appId; - - const price = 1.2; - - const lsig = await testHelper.getOrderLsig(client, creatorAccount, price, config.assetId, false); - const accountInfo = await testHelper.getAccountInfo(lsig.address()); - console.log( 'current escrow amount: ', accountInfo.amount ); - const algoAmountReceiving = accountInfo.amount - 200000; // amount to trade. rest will be closed out + console.log('STARTING executeAlgoEscrowOrder test'); + + + // const creatorAccount = config.executorAccount.addr; + const wallet = { + type: 'sdk', + address: config.executorAccount.addr, + connector: { + ...config.connector, + sk: config.executorAccount.sk, //Just in case we want to test signing and sending from the api and not from the tests. + connected: true, + }, + // mnemonic: config.creatorAccount.sk, + }; - let asaAmountSending = algoAmountReceiving / price; - if (Math.floor(asaAmountSending) != asaAmountSending) { - asaAmountSending = Math.floor(asaAmountSending) + 1; // give slightly better deal to maker - } + const order = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: config.executorAccount.addr, + price: price, + amount: takerAmount, + total: price * takerAmount, + type: 'sell', + client: config.client, + execution: 'taker', + wallet: wallet, + }; - const outerTxns = await transactionGenerator.getExecuteAlgoEscrowOrderTxns(client, executorAccount, creatorAccount, - algoAmountReceiving, asaAmountSending, price, config.assetId, appId, true); + const executePartialAlgoEscrowOrder = + await transactionGenerator.getTakerOrderTxns(order); if (returnOuterTransactions) { return outerTxns; } + const signedTxns = await signer( + executePartialAlgoEscrowOrder, + config.executorAccount.sk + ); - const signedTxns = testHelper.groupAndSignTransactions(outerTxns); - - await testHelper.sendAndCheckConfirmed(client, signedTxns); + const confirmation = await _sendTransactions(client, signedTxns); return true; }, diff --git a/lib/order/__tests__/teal_tests/placeASAEscrowOrder.js b/lib/order/__tests__/teal_tests/placeASAEscrowOrder.js index c62ec707..d2869438 100644 --- a/lib/order/__tests__/teal_tests/placeASAEscrowOrder.js +++ b/lib/order/__tests__/teal_tests/placeASAEscrowOrder.js @@ -8,35 +8,72 @@ /* eslint-disable */ const testHelper = require('../setup.js'); -const transactionGenerator = require('../../lib/teal/generate_transaction_types.js'); +const transactionGenerator = require('../GenerateTransactionTypes'); const algosdk = require('algosdk'); +const signer = require('../../../wallet/signers/AlgoSDK'); +const _sendTransactions = require('./sendTransactions'); const PRINT_TXNS = 0; const Test = { - runTest: async function(config, asaAmount, price, returnOuterTransactions) { + runTest: async function ( + config, + asaAmount, + price, + optIn, + returnOuterTransactions + ) { console.log('STARTING placeASAEscrowOrder test'); const client = config.client; - const creatorAccount = config.creatorAccount; - const appId = config.appId; - const outerTxns = await transactionGenerator.getPlaceASAEscrowOrderTxns(client, creatorAccount, asaAmount, price, config.assetId, appId); + const creatorAccount = config.creatorAccount.addr; + const wallet = { + type: 'sdk', + address: config.creatorAccount.addr, + connector: { + ...config.connector, + sk: config.creatorAccount.sk, //Just in case we want to test signing and sending from the api and not from the tests. + connected: true, + }, + // mnemonic: config.creatorAccount.sk, + }; + + const order = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: creatorAccount, + price: price, + amount: asaAmount, + total: price * asaAmount, + type: 'sell', + client: config.client, + execution: 'maker', + wallet: wallet, + }; + + const placeASAEscrowOrder = + await transactionGenerator.getPlaceASAEscrowOrderTxns(order, optIn); if (returnOuterTransactions) { return outerTxns; } - const signedTxns = testHelper.groupAndSignTransactions(outerTxns); + const signedTxns = await signer( + [placeASAEscrowOrder], + config.creatorAccount.sk + ); - await testHelper.sendAndCheckConfirmed(client, signedTxns); + const confirmation = await _sendTransactions(client, signedTxns); return true; }, - getOuterTransactions: async function(config) { + getOuterTransactions: async function (config) { const outerTxns = await this.runTest(config, 200000, 1.2, true); return outerTxns; }, - runGroupSizeWrongTest: async function(config) { + runGroupSizeWrongTest: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -47,9 +84,14 @@ const Test = { const lsig = outerTxns[1].lsig; - outerTxns.push( { - unsignedTxn: await transactionGenerator.getPayTxn(client, lsig.address(), maliciousAccount.addr, - 1000, false), + outerTxns.push({ + unsignedTxn: await transactionGenerator.getPayTxn( + client, + lsig.address(), + maliciousAccount.addr, + 1000, + false + ), lsig: lsig, }); @@ -64,7 +106,7 @@ const Test = { return false; }, - runGroupSizeWrongTest2: async function(config) { + runGroupSizeWrongTest2: async function (config) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -75,9 +117,14 @@ const Test = { const lsig = outerTxns[1].lsig; - outerTxns.push( { - unsignedTxn: await transactionGenerator.getPayTxn(client, maliciousAccount.addr, maliciousAccount.addr, - 1000, false), + outerTxns.push({ + unsignedTxn: await transactionGenerator.getPayTxn( + client, + maliciousAccount.addr, + maliciousAccount.addr, + 1000, + false + ), senderAcct: maliciousAccount, }); @@ -92,7 +139,7 @@ const Test = { return false; }, - runPayAmountTooLowTest: async function(config, skipASAOptIn = false) { + runPayAmountTooLowTest: async function (config, skipASAOptIn = false) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -116,7 +163,7 @@ const Test = { return false; }, - runAppOptInMissingTest: async function(config, skipASAOptIn = false) { + runAppOptInMissingTest: async function (config, skipASAOptIn = false) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -128,8 +175,13 @@ const Test = { const lsig = outerTxns[1].lsig; outerTxns[1] = { - unsignedTxn: await transactionGenerator.getPayTxn(client, maliciousAccount.addr, maliciousAccount.addr, - 1000, false), + unsignedTxn: await transactionGenerator.getPayTxn( + client, + maliciousAccount.addr, + maliciousAccount.addr, + 1000, + false + ), senderAcct: maliciousAccount, }; @@ -144,7 +196,7 @@ const Test = { return false; }, - runAssetIdWrongTest: async function(config, skipASAOptIn = false) { + runAssetIdWrongTest: async function (config, skipASAOptIn = false) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -168,7 +220,7 @@ const Test = { return false; }, - runAssetAmountZeroTest: async function(config, skipASAOptIn = false) { + runAssetAmountZeroTest: async function (config, skipASAOptIn = false) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -191,7 +243,7 @@ const Test = { return false; }, - runAssetRecipientWrongTest: async function(config, skipASAOptIn = false) { + runAssetRecipientWrongTest: async function (config, skipASAOptIn = false) { const outerTxns = await this.getOuterTransactions(config); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -213,6 +265,5 @@ const Test = { return false; }, - }; module.exports = Test; diff --git a/lib/order/__tests__/teal_tests/placeAlgoEscrowOrder.js b/lib/order/__tests__/teal_tests/placeAlgoEscrowOrder.js index 1a648de4..7e8217cd 100644 --- a/lib/order/__tests__/teal_tests/placeAlgoEscrowOrder.js +++ b/lib/order/__tests__/teal_tests/placeAlgoEscrowOrder.js @@ -8,23 +8,87 @@ /* eslint-disable */ const testHelper = require('../setup.js'); -const transactionGenerator = require('../../lib/teal/generate_transaction_types.js'); +const transactionGenerator = require('../GenerateTransactionTypes'); const algosdk = require('algosdk'); +const signer = require('../../../wallet/signers/AlgoSDK'); +const _sendTransactions = require('./sendTransactions'); const PRINT_TXNS = 0; const Test = { + runTest: async function ( + config, + asaAmount, + price, + optIn, + returnOuterTransactions + ) { + const client = config.client; + + const creatorAccount = config.creatorAccount.addr; + const wallet = { + type: 'sdk', + address: config.creatorAccount.addr, + connector: { + ...config.connector, + sk: config.creatorAccount.sk, //Just in case we want to test signing and sending from the api and not from the tests. + connected: true, + }, + // mnemonic: config.creatorAccount.sk, + }; + + const order = { + asset: { + id: config.assetId, + decimals: 6, + }, + address: creatorAccount, + price: price, + amount: asaAmount, + total: price * asaAmount, + type: 'buy', + client: config.client, + execution: 'maker', + wallet: wallet, + }; + + const placeAlgoEscrowOrder = + await transactionGenerator.getPlaceAlgoEscrowOrderTxns(order, optIn); + + if (returnOuterTransactions) { + return outerTxns; + } + const signedTxns = await signer( + [placeAlgoEscrowOrder], + config.creatorAccount.sk + ); + + const confirmation = await _sendTransactions(client, signedTxns); + + return true; + }, - runGroupSizeWrongTest: async function(config, skipASAOptIn = false) { - const outerTxns = await this.runTest(config, 800000, 1.375, skipASAOptIn, true); + runGroupSizeWrongTest: async function (config, skipASAOptIn = false) { + const outerTxns = await this.runTest( + config, + 800000, + 1.375, + skipASAOptIn, + true + ); const client = config.client; const maliciousAccount = config.maliciousAccount; const lsig = outerTxns[1].lsig; - outerTxns.push( { - unsignedTxn: await makePaymentTxn(client, lsig.address(), maliciousAccount.addr, - 1000, false), + outerTxns.push({ + unsignedTxn: await makePaymentTxn( + client, + lsig.address(), + maliciousAccount.addr, + 1000, + false + ), lsig: lsig, }); @@ -39,8 +103,14 @@ const Test = { return false; }, - runGroupSizeWrongTest2: async function(config, skipASAOptIn = false) { - const outerTxns = await this.runTest(config, 800000, 1.375, skipASAOptIn, true); + runGroupSizeWrongTest2: async function (config, skipASAOptIn = false) { + const outerTxns = await this.runTest( + config, + 800000, + 1.375, + skipASAOptIn, + true + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -50,9 +120,14 @@ const Test = { const lsig = outerTxns[1].lsig; - outerTxns.push( { - unsignedTxn: await transactionGenerator.getPayTxn(client, maliciousAccount.addr, maliciousAccount.addr, - 1000, false), + outerTxns.push({ + unsignedTxn: await transactionGenerator.getPayTxn( + client, + maliciousAccount.addr, + maliciousAccount.addr, + 1000, + false + ), senderAcct: maliciousAccount, }); @@ -67,8 +142,14 @@ const Test = { return false; }, - runPayAmountTooLowTest: async function(config, skipASAOptIn = false) { - const outerTxns = await this.runTest(config, 800000, 1.375, skipASAOptIn, true); + runPayAmountTooLowTest: async function (config, skipASAOptIn = false) { + const outerTxns = await this.runTest( + config, + 800000, + 1.375, + skipASAOptIn, + true + ); const client = config.client; const maliciousAccount = config.maliciousAccount; @@ -91,8 +172,14 @@ const Test = { return false; }, - runPayNotToLsigTest: async function(config, skipASAOptIn = false) { - const outerTxns = await this.runTest(config, 800000, 1.375, skipASAOptIn, true); + runPayNotToLsigTest: async function (config, skipASAOptIn = false) { + const outerTxns = await this.runTest( + config, + 800000, + 1.375, + skipASAOptIn, + true + ); const client = config.client; const maliciousAccount = config.maliciousAccount; diff --git a/lib/order/__tests__/teal_tests/sendTransactions.js b/lib/order/__tests__/teal_tests/sendTransactions.js new file mode 100644 index 00000000..4fd29d1e --- /dev/null +++ b/lib/order/__tests__/teal_tests/sendTransactions.js @@ -0,0 +1,19 @@ +const algosdk = require('algosdk'); + +const _sendTransactions = async (client, signedTransactions) => { + const sentRawTxnIdArr = []; + + for (const group of signedTransactions) { + const rawTxns = group.map((txn) => txn.blob); + try { + const {txId} = await client.sendRawTransaction(rawTxns).do(); + sentRawTxnIdArr.push(txId); + } catch (e) { + console.log(e); + } + } + + await Promise.all(sentRawTxnIdArr.map((txId) => algosdk.waitForConfirmation(client, txId, 10 ))); +}; + +module.exports = _sendTransactions; diff --git a/lib/order/txns/buy/makeExecuteAlgoTxns.spec.js b/lib/order/txns/buy/makeExecuteAlgoTxns.spec.js index 495a81b7..f91358c6 100644 --- a/lib/order/txns/buy/makeExecuteAlgoTxns.spec.js +++ b/lib/order/txns/buy/makeExecuteAlgoTxns.spec.js @@ -85,7 +85,7 @@ describe.skip('makeExecuteAlgoTxns', () => { // }; // }).forEach(({order, exist, optIn})=>{ let signedTxns; - it('should create ExecuteAlgoTxns', async () => { + it.skip('should create ExecuteAlgoTxns', async () => { const openBuyOrder = (await config.api.http.dexd.fetchOrders('wallet', 'UUEUTRNQY7RUXESXRDO7HSYRSJJSSVKYVB4DI7X2HVVDWYOBWJOP5OSM3A')).filter((o) => o.type === 'buy')[0]; openBuyOrder.wallet = config.api.wallet; openBuyOrder.client = config.client; diff --git a/lib/teal/test/initAccounts.js b/lib/teal/test/initAccounts.js index fe9e2bca..bcecc589 100644 --- a/lib/teal/test/initAccounts.js +++ b/lib/teal/test/initAccounts.js @@ -1,3 +1,5 @@ +/* eslint-disable */ + /* * Copyright (C) 2021-2022 Algodex VASP (BVI) Corp. * @@ -6,7 +8,6 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -const algosdk = require('algosdk'); const {transferFunds, transferASA} = require('../utils'); /** @@ -16,32 +17,31 @@ const {transferFunds, transferASA} = require('../utils'); * @param {boolean} newCreator * @return {Promise} */ -async function initAccounts(config, optIn = false, newCreator = false) { - // If we are overriding the default creator account - if (newCreator) { - // This creates the config.oldCreatorAccount key - // and overrides the current creator account - config.setCreatorAccount(algosdk.generateAccount()); - } - await transferFunds(config.client, config.openAccount, config.creatorAccount, 2000000); - - const {client, openAccount, maliciousAccount, creatorAccount, executorAccount} = config; +async function initAccounts(config, type, optIn = false, note) { + // If we are overriding the default creator account + const { + client, + openAccount, + creatorAccount, + assetId, + } = config; - await transferFunds(client, openAccount, creatorAccount, 5000000); // 5 algos - await transferFunds(client, openAccount, executorAccount, 5000000); // 5 algos - await transferASA(client, creatorAccount, creatorAccount, 0, config.assetIndex); // opt in transaction - await transferASA(client, openAccount, creatorAccount, 2000000, config.assetIndex); // 5 algos + await transferFunds(client, openAccount, creatorAccount, 2000000, note); - if (optIn) { - await transferASA(client, executorAccount, executorAccount, 0, config.assetIndex); // opt in transaction - await transferASA(client, openAccount, executorAccount, 2000000, config.assetIndex); // 5 algos + if (type === 'sell') { + // escrowPlaceOrder + await transferASA(client, creatorAccount, creatorAccount, 0, assetId, note); // opt in transaction + await transferASA(client, openAccount, creatorAccount, 2000000, assetId, note); // testASA } - await transferFunds(client, openAccount, maliciousAccount, 5000000); // 5 algos - await transferASA(client, maliciousAccount, maliciousAccount, 0, config.assetIndex); // opt in transaction - await transferASA(client, openAccount, maliciousAccount, 2000000, config.assetIndex); // 5 algos + if (type === 'buy') { + // await transferFunds(client, openAccount, creatorAccount, 5000000); //enough funds to facilitate an escrow place + if (optIn) { + await transferASA(client, creatorAccount, creatorAccount, 0, assetId, note); // opt in transaction + } + } } module.exports = initAccounts; diff --git a/lib/teal/test/initExecutor.js b/lib/teal/test/initExecutor.js new file mode 100644 index 00000000..d4014158 --- /dev/null +++ b/lib/teal/test/initExecutor.js @@ -0,0 +1,28 @@ +const {transferFunds, transferASA} = require('../utils'); +/** + * + * @param {TestConfig} config + * @param {String} type + * @param {boolean} optIn + * @param {string} note + * @return {Promise} + */ +async function initExecutor(config, type, optIn, note) { + // If we are overriding the default creator account + + const {client, openAccount, executorAccount, assetId} = config; + + await transferFunds(client, openAccount, executorAccount, 2000000, note); + + if (type === 'sell' && optIn === true) { + await transferASA(client, executorAccount, executorAccount, 0, assetId, note); // opt in transaction + } + + if (type === 'buy') { + // executor is willing to sell an asset + await transferASA(client, executorAccount, executorAccount, 0, assetId, note); // opt in transaction + await transferASA(client, openAccount, executorAccount, 2000000, assetId, note); // provide executor account with assset to sell + } +} + +module.exports = initExecutor; diff --git a/lib/teal/utils.js b/lib/teal/utils.js index 1f22db45..1133466b 100644 --- a/lib/teal/utils.js +++ b/lib/teal/utils.js @@ -16,17 +16,18 @@ const getTransactionParams = require('./getTransactionParams'); * @deprecated * @type {string} */ -const ALGOD_SERVER='http:/ec2-3-18-80-65.us-east-2.compute.amazonaws.com'; +const ALGOD_SERVER = 'http:/ec2-3-18-80-65.us-east-2.compute.amazonaws.com'; /** * @deprecated * @type {string} */ -const ALGOD_TOKEN = '11e4dcfb445a8c7e8380848747f18afcd5d84ccb395e003e5b72127ca5e9a259'; // { 'X-API-Key': 'VELyABA1dGqGbAVktbew4oACvp0c0298gMgYtYIb' } +const ALGOD_TOKEN = + '11e4dcfb445a8c7e8380848747f18afcd5d84ccb395e003e5b72127ca5e9a259'; // { 'X-API-Key': 'VELyABA1dGqGbAVktbew4oACvp0c0298gMgYtYIb' } /** * @deprecated * @type {string} */ -const ALGOD_PORT='8080'; +const ALGOD_PORT = '8080'; /** * @param {string} addr @@ -35,9 +36,9 @@ const ALGOD_PORT='8080'; */ async function getAccountInfo(addr) { try { - const port = (ALGOD_PORT) ? ':' + ALGOD_PORT : ''; + const port = ALGOD_PORT ? ':' + ALGOD_PORT : ''; const response = await axios.get( - ALGOD_SERVER + port + '/v2/accounts/'+addr, + ALGOD_SERVER + port + '/v2/accounts/' + addr, {headers: {'X-Algo-API-Token': ALGOD_TOKEN}}, ); return response.data; @@ -46,6 +47,13 @@ async function getAccountInfo(addr) { throw new Error(`getAccountInfo failed: ${e.message}`); } } +/** + * @param {number} ms + * @return {Promise} + */ +function timeout(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} /** * Send Groups Transactions @@ -58,13 +66,14 @@ async function sendGroupsTransactions(client, groupsOfTransactions) { // terrible practice but fine for the time being. for (const group in groupsOfTransactions) { if (group !== 'prototype') { - const {txId} = await client.sendRawTransaction(groupsOfTransactions[group]).do(); + const {txId} = await client + .sendRawTransaction(groupsOfTransactions[group]) + .do(); await algosdk.waitForConfirmation(client, txId, 10); } } } - /** * Check Pending * @@ -74,7 +83,11 @@ async function sendGroupsTransactions(client, groupsOfTransactions) { */ async function checkPending(client, txId) { const pendingInfo = await client.pendingTransactionInformation(txId).do(); - if (pendingInfo != null && pendingInfo.txn != null && pendingInfo.txn.txn != null) { + if ( + pendingInfo != null && + pendingInfo.txn != null && + pendingInfo.txn.txn != null + ) { return pendingInfo; } else { console.log('Looping'); @@ -90,12 +103,20 @@ async function checkPending(client, txId) { * @return {Promise} */ async function waitForConfirmation(client, txId) { - const status = (await client.status().do()); + const status = await client.status().do(); let lastRound = status['last-round']; const pendingInfo = await client.pendingTransactionInformation().do(); - if (pendingInfo['confirmed-round'] !== null && pendingInfo['confirmed-round'] > 0) { + if ( + pendingInfo['confirmed-round'] !== null && + pendingInfo['confirmed-round'] > 0 + ) { // Got the completed Transaction - logger.debug('Transaction ' + txId + ' confirmed in round ' + pendingInfo['confirmed-round']); + logger.debug( + 'Transaction ' + + txId + + ' confirmed in round ' + + pendingInfo['confirmed-round'], + ); return pendingInfo; } else { lastRound++; @@ -144,7 +165,7 @@ async function deleteApplication(client, sender, appId) { try { await client.sendRawTransaction(signedTxn).do(); } catch (e) { - logger.error({'fn': 'deleteApplication'}, e.message ); + logger.error({fn: 'deleteApplication'}, e.message); } // display results await algosdk.waitForConfirmation(client, txId, 10); @@ -158,21 +179,42 @@ async function deleteApplication(client, sender, appId) { * @return {Promise} */ async function closeAccount(client, fromAccount, toAccount) { - logger.debug('teal.closeAccount - checking account info for: ' + fromAccount.addr); + logger.debug( + 'teal.closeAccount - checking account info for: ' + fromAccount.addr, + ); const fromAccountInfo = await getAccountInfo(fromAccount.addr); - if (fromAccountInfo != null && fromAccountInfo['assets'] != null && - fromAccountInfo['assets'].length > 0) { + if ( + fromAccountInfo != null && + fromAccountInfo['assets'] != null && + fromAccountInfo['assets'].length > 0 + ) { for (let i = 0; i < fromAccountInfo['assets'].length; i++) { const asset = fromAccountInfo['assets'][i]; const assetId = asset['asset-id']; - logger.info('closing asset: ' + assetId + ' for account: ' + fromAccount.addr); - const txn = await txns.makeAssetTransferTxn(client, fromAccount, toAccount, 0, assetId, undefined, true); + logger.info( + 'closing asset: ' + assetId + ' for account: ' + fromAccount.addr, + ); + const txn = await txns.makeAssetTransferTxn( + client, + fromAccount, + toAccount, + 0, + assetId, + undefined, + true, + ); const signedTxn = algosdk.signTransaction(txn, fromAccount.sk); await sendAndCheckPending(client, [signedTxn.blob]); } } - const fundTxn = await txns.makePaymentTxn(client, fromAccount, toAccount, 0, true); + const fundTxn = await txns.makePaymentTxn( + client, + fromAccount, + toAccount, + 0, + true, + ); const fundTxnId = fundTxn.txID().toString(); const signedTxn = fundTxn.signTxn(fromAccount.sk); logger.info('Signed transaction with txID: %s', fundTxnId); @@ -190,11 +232,19 @@ async function closeAccount(client, fromAccount, toAccount) { * @param {algosdk.Account} fromAccount * @param {algosdk.Account} toAccount * @param {number} amount + * @param {string} note * @return {Promise} */ -async function transferFunds(client, fromAccount, toAccount, amount) { - const fundTxn = await txns.makePaymentTxn( - client, fromAccount, toAccount, amount, false, +async function transferFunds(client, fromAccount, toAccount, amount, note) { + const _suggestedParams = await client.getTransactionParams().do(); + const fundTxn = algosdk.makePaymentTxnWithSuggestedParams( + fromAccount.addr, + toAccount.addr, + amount, + undefined, + note, + _suggestedParams, + undefined, ); const fundTxnId = fundTxn.txID().toString(); @@ -220,11 +270,14 @@ async function transferFunds(client, fromAccount, toAccount, amount) { async function getAssetBalance(accountAddr, assetId) { logger.debug('checking account info for: ' + accountAddr); const accountInfo = await getAccountInfo(accountAddr); - if (accountInfo != null && accountInfo['assets'] != null && - accountInfo['assets'].length > 0) { + if ( + accountInfo != null && + accountInfo['assets'] != null && + accountInfo['assets'].length > 0 + ) { for (let i = 0; i < accountInfo['assets'].length; i++) { const asset = accountInfo['assets'][i]; - logger.debug({asset} ); + logger.debug({asset}); if (asset['asset-id'] === assetId) { return asset['amount']; } @@ -253,10 +306,16 @@ function groupAndSignTransactions(outerTxns) { for (let i = 0; i < outerTxns.length; i++) { const txn = outerTxns[i]; if (txn.lsig != null) { - const signedLsig = algosdk.signLogicSigTransactionObject(txn.unsignedTxn, txn.lsig); + const signedLsig = algosdk.signLogicSigTransactionObject( + txn.unsignedTxn, + txn.lsig, + ); txn.signedTxn = signedLsig.blob; } else { - const signedTxn = algosdk.signTransaction(txn.unsignedTxn, txn.senderAcct.sk); + const signedTxn = algosdk.signTransaction( + txn.unsignedTxn, + txn.senderAcct.sk, + ); txn.signedTxn = signedTxn.blob; } } @@ -278,16 +337,23 @@ function groupAndSignTransactions(outerTxns) { * @param {algosdk.Account} toAccount * @param {number} amount * @param {string|number} assetId + * @param {string} note * @return {Promise} */ -async function transferASA( - client, - fromAccount, - toAccount, - amount, - assetId, -) { - const asaTransferTxn = await txns.makeAssetTransferTxn(client, fromAccount, toAccount, amount, assetId, false); +async function transferASA(client, fromAccount, toAccount, amount, assetId, note) { + const _suggestedParams = await client.getTransactionParams().do(); + + const asaTransferTxn = algosdk.makeAssetTransferTxnWithSuggestedParams( + fromAccount.addr, + toAccount.addr, + undefined, + undefined, + amount, + note, + assetId, + _suggestedParams, + undefined, + ); const asaTxnId = asaTransferTxn.txID().toString(); const signedFundTxn = asaTransferTxn.signTxn(fromAccount.sk); @@ -316,4 +382,5 @@ module.exports = { sendAndCheckPending, waitForConfirmation, groupAndSignTransactions, + timeout, }; diff --git a/package.json b/package.json index 1caed82d..c4bdf4c4 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "doc-types": "tsc", "test": "yarn test-lint && yarn test-unit && yarn test-integration", "test-lint": "eslint . --quiet", - "test-unit": "jest", + "test-unit": "jest --testPathIgnorePatterns='__tests__/*'", "test-integration": "cross-env TEST_ENV=integration jest", "coverage": "yarn test-unit --coverage", "test-sanity": "jest --testPathIgnorePatterns='__tests__/*' --testPathIgnorePatterns='./lib/*' --coverage",