diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f302fb68..a18e10ee4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,32 @@ ## unreleased +### API breaking ++ Rename `SSC` to `App` - This will affect deployment and all calls made to stateful smart contracts(SSC) or `App` + + OptInSSC -> OptInToASA + + DeleteSSC -> DeleteApp + + DeploySSC -> DeployApp + + SSCDeploymentFlags -> AppDeploymentFlags + + SSCOptionalFlags -> AppOptionalFlags ++ Import are changed to scoped imports + + instead of stringToBytes, you can import a `convert` namespace, and then use `convert.stringToBytes` ++ Types imports for `ExecParams`, `TransactionTypes`, `SignType` moved to new package `@algo-builder/web` + + +### Improvements ++ updated `algob test` command to run mocha in typescript project as well. ++ Add workflow for examples ++ New package `Web`, It can be used in Dapps to interact with ASAs and Apps + + Compatible with `algosigner`. + + Support `executeTransaction` function with web package ++ Move Error lists, BuilderError, mkTransaction to web package ++ Reuse mkTransaction, Errors in algob and runtime + ### Infrastructure * Added new make commands: * `setup-reach` - sets up reach executable file in `~/.algorand-reach` directory * `remove-reach` - halts any dockerized devnets, kills & removes docker instances and containers, remove reach bash file from `~/.algorand-reach`. -### Improvements -+ updated `algob test` command to run mocha in typescript project as well. -+ Add workflow for examples ## v1.1.0 2021-06-23 @@ -20,7 +38,7 @@ Highlights: + checkpoint can be market invalid if they are substituted (eg by redeploying same asset). ### API breaking -* Move `updateSSC` function to `deployer` +* Move `updateApp` function to `deployer` + Rename `parseArgs` to `parse_params` + For External support of parameters user should replace TMPL_ prefix in their smart contracts, and only use it when using pyteal.tmpl(..) @@ -31,12 +49,12 @@ Highlights: + Added `algopy` in `@algo-builder/algob/sample-project`, which enables users to pass template parameters to PyTEAL contracts. Updated docs. + Store checkpoints in nested form for SSC, added tests. + Added support for sub directories in assets folder, with tests. -+ Update runtime to process execParams.deployASA, deploySSC, OptInToASA, OptIntoSSC ++ Update runtime to process execParams.deployASA, deployApp, OptInToASA, OptIntoSSC + Exported `@algorand-builder/algob`, `@algorand-builder/runtime` error types and make it accessible for API documentation. + Added `debugStack` option in `runtime.executeTx()` to print stack (upto depth = debugStack) after each opcode execution. + TEALv3 support in `@algo-builder/runtime`. + Transpile TEAL code to substitute the TMPL placeholders -+ Mark not valid checkpoints (in case of `DeleteSSC`/`DestroyAsset`) using `deleted` boolean ++ Mark not valid checkpoints (in case of `deleteApp`/`DestroyAsset`) using `deleted` boolean ### Bug fixes @@ -91,7 +109,7 @@ New website: https://scale-it.github.io/algo-builder * New opt-in functions and updates. Check the [deployer API](https://scale-it.github.io/algo-builder/api/algob/interfaces/types.deployer.html) for information about all opt-in functions. * `deployer.optIn` are now available both in *DEPLOY* mode to *RUN* mode. * Extended `deployer.optIn*` functions to support ASA by ID. Previously we only accepted ASA by name (based on the name in `assets/asa.yaml` file). - * Added [`deployer.optInLsigToSSC`](https://scale-it.github.io/algo-builder/api/algob/interfaces/types.deployer.html#optinlsigtossc) and [`deployer.optInLsigToASA`](https://scale-it.github.io/algo-builder/api/algob/interfaces/types.deployer.html#optinlsigtoasa) to easily opt-in stateless smart contract (lsig) account to stateful smart contract and ASA. + * Added [`deployer.optInLsigToApp`](https://scale-it.github.io/algo-builder/api/algob/interfaces/types.deployer.html#optinlsigtoapp) and [`deployer.optInLsigToASA`](https://scale-it.github.io/algo-builder/api/algob/interfaces/types.deployer.html#optinlsigtoasa) to easily opt-in stateless smart contract (lsig) account to stateful smart contract and ASA. * Asset related `execParams` (transaction parameters for [`executeTransaction`](https://scale-it.github.io/algo-builder/api/algob/modules.html#executetransaction)) support ASA by name and by ID (previously only ASA ID was supported). [Example](https://github.com/scale-it/algo-builder/blob/master/examples/asa/scripts/transfer/gold-delegated-lsig.js#L22). * cleaned test suite log (when developing Algo Builder itself). Our test suite has 884 tests. diff --git a/docs/guide/deployer.md b/docs/guide/deployer.md index 8d4f36e8c..fa66e39ce 100644 --- a/docs/guide/deployer.md +++ b/docs/guide/deployer.md @@ -86,11 +86,11 @@ You can deploy Stateful/Stateless Smart Contracts (SSC). #### Stateful Smart Contracts Check our [examples/permissioned-voting](https://github.com/scale-it/algo-builder/tree/master/examples/permissioned-voting) project. Open the `scripts/voting.js` file, you will find there: - await deployer.deploySSC("approval.teal", "clear.teal", {...}); + await deployer.deployApp("approval.teal", "clear.teal", {...}); Smart contracts must be stored in `assets` folder. -The main difference between deploying an ASA and SSC is that ASA takes `asset-name` and `ASADeploymentFlags` as input and SSC takes `smart-contract-names` and `SSCDeploymentFlags` as input. +The main difference between deploying an ASA and SSC is that ASA takes `asset-name` and `ASADeploymentFlags` as input and SSC takes `smart-contract-names` and `AppDeploymentFlags` as input. You can learn more about the flags from [Deployer API](https://scale-it.github.io/algo-builder/api/algob/interfaces/types.deployer.html); You can learn more about Stateful Smart Contracts [here](https://developer.algorand.org/docs/features/asc1/stateful/). @@ -99,7 +99,7 @@ You can learn more about Stateful Smart Contracts [here](https://developer.algor For opting in to SSC, `deployer` supports the following methods: - `optInAcountToSSC` to opt-in to a single account signed by secret key of sender. -- `optInLsigToSSC` to opt-in to a contract account (say escrow) where the account is represented by the logic signature address (`lsig.address()`). +- `optInLsigToApp` to opt-in to a contract account (say escrow) where the account is represented by the logic signature address (`lsig.address()`). - To opt in to SSC you can use `Application Index`.[When the smart contract is created the network will return a unique ApplicationID. This ID can then be used to make ApplicationCall transactions to the smart contract. ](https://developer.algorand.org/docs/features/asc1/stateful/#call-the-stateful-smart-contract) - Like with ASA, we can also use `executeTransaction` to opt-in a single account or contract account to SSC. @@ -107,7 +107,7 @@ For opting in to SSC, `deployer` supports the following methods: - Ex: To opt-in a single account, Params will look like this: ```js const execParam: ExecParams = { - type: TransactionType.OptInSSC, + type: TransactionType.OptInToApp, sign: SignType.SecretKey, fromAccount: user.account, appID: appID, @@ -117,7 +117,7 @@ For opting in to SSC, `deployer` supports the following methods: - Ex: To opt-in to a contract account ```js const execParam: ExecParams = { - type: TransactionType.OptInSSC, + type: TransactionType.OptInToApp, sign: SignType.LogicSignature, fromAccountAddr: lsig.address(), appID: appID, diff --git a/docs/guide/execute-transaction.md b/docs/guide/execute-transaction.md index 82c3ab15b..c17763a16 100644 --- a/docs/guide/execute-transaction.md +++ b/docs/guide/execute-transaction.md @@ -4,7 +4,7 @@ layout: splash # Execute Transaction -`executeTransaction` is a high level function which can be used to perform transactions on Algorand Network. It supports every transaction (atomic or single) which is possible in network. Ex: Deploy ASA/SSC, Opt-In, Transfers, Delete, Destroy etc. `executeTransaction` takes `ExecParams` or `ExecParams[]` as parameter. +`executeTransaction` is a high level function which can be used to perform transactions on Algorand Network. It supports every transaction (atomic or single) which is possible in network. Ex: Deploy ASA/App, Opt-In, Transfers, Delete, Destroy etc. `executeTransaction` takes `ExecParams` or `ExecParams[]` as parameter. If you pass an array of `ExecParams`, it will be considered as `atomic transaction`. In below sections we will demonstrate how to pass these parameters. @@ -79,11 +79,11 @@ Examples of parameter [`ExecParams`](https://algobuilder.dev/api/algob/modules/r } ``` -### [Deploy SSC](https://algobuilder.dev/api/algob/modules/runtime.types.html#deploysscparam) +### [Deploy App](https://algobuilder.dev/api/algob/modules/runtime.types.html#deployappparam) ```js { - type: TransactionType.DeploySSC, + type: TransactionType.DeployApp, sign: SignType.SecretKey, fromAccount: john, approvalProgram: approvalProgram, @@ -95,13 +95,13 @@ Examples of parameter [`ExecParams`](https://algobuilder.dev/api/algob/modules/r payFlags: {} } ``` -- To learn about more parameters like (account, appArgs, ForeignApps, ForeignAssets etc).Please check [SSCOptionalFlags](https://algobuilder.dev/api/algob/interfaces/runtime.types.sscoptionalflags.html) +- To learn about more parameters like (account, appArgs, ForeignApps, ForeignAssets etc).Please check [AppOptionalFlags](https://algobuilder.dev/api/algob/interfaces/runtime.types.AppOptionalFlags.html) -### [Opt-In to SSC](https://algobuilder.dev/api/algob/modules/runtime.types.html#optinsscparam) +### [Opt-In to App](https://algobuilder.dev/api/algob/modules/runtime.types.html#optintoappparam) ```js { - type: TransactionType.OptInSSC, + type: TransactionType.OptInToApp, sign: SignType.SecretKey, fromAccount: alice, appID: appID, @@ -109,11 +109,11 @@ Examples of parameter [`ExecParams`](https://algobuilder.dev/api/algob/modules/r } ``` -### [Call SSC](https://algobuilder.dev/api/algob/modules/runtime.types.html#ssccallsparam) +### [Call App](https://algobuilder.dev/api/algob/modules/runtime.types.html#appcallsparam) ```js { - type: TransactionType.CallNoOpSSC, + type: TransactionType.CallNoOpApp, sign: SignType.SecretKey, fromAccount: john, appId: 0, @@ -121,11 +121,11 @@ Examples of parameter [`ExecParams`](https://algobuilder.dev/api/algob/modules/r } ``` -### [Update SSC](https://algobuilder.dev/api/algob/modules/runtime.types.html#updatesscparam) +### [Update App](https://algobuilder.dev/api/algob/modules/runtime.types.html#updateappparam) ```js { - type: TransactionType.UpdateSSC, + type: TransactionType.updateApp, sign: SignType.SecretKey, fromAccount: john, appID: appId, @@ -135,11 +135,11 @@ Examples of parameter [`ExecParams`](https://algobuilder.dev/api/algob/modules/r } ``` -### [Delete SSC](https://algobuilder.dev/api/algob/modules/runtime.types.html#ssccallsparam) +### [Delete App](https://algobuilder.dev/api/algob/modules/runtime.types.html#appcallsparam) ```js { - type: TransactionType.DeleteSSC, + type: TransactionType.DeleteApp, sign: SignType.SecretKey, fromAccount: john, appId: 10, diff --git a/docs/guide/py-teal.md b/docs/guide/py-teal.md index 67a8abac8..2b229b0d5 100644 --- a/docs/guide/py-teal.md +++ b/docs/guide/py-teal.md @@ -28,7 +28,7 @@ Please follow the main [README#PyTeal](https://github.com/scale-it/algo-builder# If the address is loaded dynamically (eg from KMD), we can't use PyTEAL code prior to the address knowledge. - If we have to deploy same contract multiple times with only difference of initialization variables, we will have to change the variables in PyTeal code everytime we deploy it. - To solve this problem we have introduced a support for passing `external parameters`. -- Deployer functions(`loadLogic`, `fundLsig`, `deploySSC`) take one extra optional argument: a smart contract parameters object(`scInitParam`). This argument is passed to PyTEAL script. +- Deployer functions(`loadLogic`, `fundLsig`, `deployApp`) take one extra optional argument: a smart contract parameters object(`scInitParam`). This argument is passed to PyTEAL script. - Changing parameters will change a generated TEAL code. Hence it the Delegated Signature or Smart Contract address will be different and we may need to redeploy it. ### Usage diff --git a/examples/asa/scripts/2-gold-asc.js b/examples/asa/scripts/2-gold-asc.js index 5ce9c8f1e..eb515db9c 100644 --- a/examples/asa/scripts/2-gold-asc.js +++ b/examples/asa/scripts/2-gold-asc.js @@ -1,5 +1,5 @@ const { executeTransaction, balanceOf } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { mkParam } = require('./transfer/common'); async function run (runtimeEnv, deployer) { diff --git a/examples/asa/scripts/3-contract-owned-asa.js b/examples/asa/scripts/3-contract-owned-asa.js index f59100cd7..b1cece0c0 100644 --- a/examples/asa/scripts/3-contract-owned-asa.js +++ b/examples/asa/scripts/3-contract-owned-asa.js @@ -9,7 +9,7 @@ */ const { executeTransaction } = require('@algo-builder/algob'); const { mkParam } = require('./transfer/common'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); @@ -19,7 +19,7 @@ async function run (runtimeEnv, deployer) { // Create Application // Note: An Account can have maximum of 10 Applications. - const sscInfo = await deployer.deploySSC( + const appInfo = await deployer.deployApp( '5-contract-asa-stateful.py', // approval program '5-clear.py', // clear program { @@ -30,10 +30,10 @@ async function run (runtimeEnv, deployer) { globalBytes: 1 }, {}); - console.log(sscInfo); + console.log(appInfo); // Get Statless Account Address - const statelessAccount = await deployer.loadLogic('5-contract-asa-stateless.py', { APP_ID: sscInfo.appID }); + const statelessAccount = await deployer.loadLogic('5-contract-asa-stateless.py', { APP_ID: appInfo.appID }); console.log('stateless Account Address:', statelessAccount.address()); await executeTransaction(deployer, mkParam(masterAccount, statelessAccount.address(), 200e6, { note: 'funding account' })); @@ -44,7 +44,7 @@ async function run (runtimeEnv, deployer) { type: types.TransactionType.CallNoOpSSC, sign: types.SignType.SecretKey, fromAccount: alice, - appID: sscInfo.appID, + appID: appInfo.appID, payFlags: {} }, // Asset creation diff --git a/examples/asa/scripts/transfer/common.js b/examples/asa/scripts/transfer/common.js index cd93937b1..208b44058 100644 --- a/examples/asa/scripts/transfer/common.js +++ b/examples/asa/scripts/transfer/common.js @@ -1,5 +1,5 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); exports.executeTransaction = async function (deployer, txnParams) { try { diff --git a/examples/asa/scripts/transfer/contract-owned-asa/change-contract-owner.js b/examples/asa/scripts/transfer/contract-owned-asa/change-contract-owner.js index 278c5e2ae..032023e53 100644 --- a/examples/asa/scripts/transfer/contract-owned-asa/change-contract-owner.js +++ b/examples/asa/scripts/transfer/contract-owned-asa/change-contract-owner.js @@ -4,7 +4,7 @@ * smart contract account(stateless). */ const { executeTransaction, convert } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { mkParam } = require('../common'); async function run (runtimeEnv, deployer) { @@ -15,7 +15,7 @@ async function run (runtimeEnv, deployer) { await executeTransaction(deployer, mkParam(masterAccount, alice.addr, 5e6, { note: 'Funding' })); // Get AppInfo from checkpoint. - const appInfo = deployer.getSSC('5-contract-asa-stateful.py', '5-clear.py'); + const appInfo = deployer.getApp('5-contract-asa-stateful.py', '5-clear.py'); // App argument to change_owner. const appArgs = [convert.stringToBytes('change_owner'), convert.addressToPk(bob.addr)]; diff --git a/examples/asa/scripts/transfer/contract-owned-asa/contract-to-alice.js b/examples/asa/scripts/transfer/contract-owned-asa/contract-to-alice.js index f26aea75b..75de0d20f 100644 --- a/examples/asa/scripts/transfer/contract-owned-asa/contract-to-alice.js +++ b/examples/asa/scripts/transfer/contract-owned-asa/contract-to-alice.js @@ -7,7 +7,7 @@ * + fee is <= 1000 * + we don't do any rekey, closeRemainderTo */ -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { balanceOf } = require('@algo-builder/algob'); const { executeTransaction, mkParam } = require('../common'); @@ -19,7 +19,7 @@ async function run (runtimeEnv, deployer) { await executeTransaction(deployer, mkParam(masterAccount, alice.addr, 5e6, { note: 'Funding' })); // Get AppInfo and AssetID from checkpoints. - const appInfo = deployer.getSSC('5-contract-asa-stateful.py', '5-clear.py'); + const appInfo = deployer.getApp('5-contract-asa-stateful.py', '5-clear.py'); const lsig = await deployer.loadLogic('5-contract-asa-stateless.py', { APP_ID: appInfo.appID }); /* Transfer ASA 'gold' from contract account to user account */ diff --git a/examples/asa/scripts/transfer/contract-owned-asa/contract-to-bob.js b/examples/asa/scripts/transfer/contract-owned-asa/contract-to-bob.js index 708b708d4..8decd341e 100644 --- a/examples/asa/scripts/transfer/contract-owned-asa/contract-to-bob.js +++ b/examples/asa/scripts/transfer/contract-owned-asa/contract-to-bob.js @@ -4,7 +4,7 @@ * from a contract account (lsig) to an changed owner account. * Note: This transfer will only work if owner is changed to bob */ -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { balanceOf } = require('@algo-builder/algob'); const { executeTransaction, mkParam } = require('../common'); @@ -15,7 +15,7 @@ async function run (runtimeEnv, deployer) { await executeTransaction(deployer, mkParam(masterAccount, bob.addr, 5e6, { note: 'Funding' })); // Get AppInfo and AssetID from checkpoints. - const appInfo = deployer.getSSC('5-contract-asa-stateful.py', '5-clear.py'); + const appInfo = deployer.getApp('5-contract-asa-stateful.py', '5-clear.py'); const lsig = await deployer.loadLogic('5-contract-asa-stateless.py', { APP_ID: appInfo.appID }); /* Transfer ASA 'gold' from contract account to user account */ diff --git a/examples/asa/scripts/transfer/gold-contract-sc.js b/examples/asa/scripts/transfer/gold-contract-sc.js index 9dba227a1..e1913b3cb 100644 --- a/examples/asa/scripts/transfer/gold-contract-sc.js +++ b/examples/asa/scripts/transfer/gold-contract-sc.js @@ -7,7 +7,7 @@ * + fee is <= 1000 * + we don't do any rekey, closeRemainderTo */ -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { balanceOf } = require('@algo-builder/algob'); const { executeTransaction } = require('./common'); diff --git a/examples/asa/scripts/transfer/gold-delegated-lsig.js b/examples/asa/scripts/transfer/gold-delegated-lsig.js index 649446e67..53ab40826 100644 --- a/examples/asa/scripts/transfer/gold-delegated-lsig.js +++ b/examples/asa/scripts/transfer/gold-delegated-lsig.js @@ -4,7 +4,7 @@ * using delegated lsig (between 2 user accounts). */ const { executeTransaction } = require('./common'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const goldOwner = deployer.accountsByName.get('alice'); diff --git a/examples/asa/scripts/transfer/gold-to-john.js b/examples/asa/scripts/transfer/gold-to-john.js index e2b4cb966..0366c5025 100644 --- a/examples/asa/scripts/transfer/gold-to-john.js +++ b/examples/asa/scripts/transfer/gold-to-john.js @@ -4,7 +4,7 @@ */ const { executeTransaction, balanceOf } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { // query gold ASA from deployer (using checkpoint information), diff --git a/examples/asa/scripts/transfer/tesla-to-john.js b/examples/asa/scripts/transfer/tesla-to-john.js index ba721a1b6..630c99c98 100644 --- a/examples/asa/scripts/transfer/tesla-to-john.js +++ b/examples/asa/scripts/transfer/tesla-to-john.js @@ -1,5 +1,5 @@ const { executeTransaction, balanceOf } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const teslaAssetID = deployer.asa.get('tesla').assetIndex; diff --git a/examples/crowdfunding/scripts/createApp.js b/examples/crowdfunding/scripts/createApp.js index 1e68b1fb5..d88779c24 100644 --- a/examples/crowdfunding/scripts/createApp.js +++ b/examples/crowdfunding/scripts/createApp.js @@ -1,7 +1,7 @@ const { executeTransaction, convert } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); @@ -38,7 +38,7 @@ async function run (runtimeEnv, deployer) { // Create Application // Note: An Account can have maximum of 10 Applications. - const sscInfo = await deployer.deploySSC( + const appInfo = await deployer.deployApp( 'crowdFundApproval.teal', // approval program 'crowdFundClear.teal', // clear program { @@ -50,20 +50,20 @@ async function run (runtimeEnv, deployer) { appArgs: appArgs }, {}); - console.log(sscInfo); + console.log(appInfo); // Get Escrow Account Address - const escrowAccount = await deployer.loadLogic('crowdFundEscrow.py', { APP_ID: sscInfo.appID }); + const escrowAccount = await deployer.loadLogic('crowdFundEscrow.py', { APP_ID: appInfo.appID }); console.log('Escrow Account Address:', escrowAccount.address()); // Update application with escrow account // Note: that the code for the contract will not change. // The update operation links the two contracts. - const applicationID = sscInfo.appID; + const applicationID = appInfo.appID; appArgs = [convert.addressToPk(escrowAccount.address())]; - const updatedRes = await deployer.updateSSC( + const updatedRes = await deployer.updateApp( creatorAccount, {}, // pay flags applicationID, @@ -75,8 +75,8 @@ async function run (runtimeEnv, deployer) { console.log('Opting-In for Creator and Donor.'); try { - await deployer.optInAccountToSSC(creatorAccount, applicationID, {}, {}); - await deployer.optInAccountToSSC(donorAccount, applicationID, {}, {}); + await deployer.optInAccountToApp(creatorAccount, applicationID, {}, {}); + await deployer.optInAccountToApp(donorAccount, applicationID, {}, {}); } catch (e) { console.log(e); throw new Error(e); diff --git a/examples/crowdfunding/scripts/transfer/claim.js b/examples/crowdfunding/scripts/transfer/claim.js index cb1521b0b..4f7aa539e 100644 --- a/examples/crowdfunding/scripts/transfer/claim.js +++ b/examples/crowdfunding/scripts/transfer/claim.js @@ -1,5 +1,5 @@ const { executeTransaction, convert } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); @@ -15,7 +15,7 @@ async function run (runtimeEnv, deployer) { }); const appArgs = [convert.stringToBytes('claim')]; - const appInfo = deployer.getSSC('crowdFundApproval.teal', 'crowdFundClear.teal'); // get from checkpoint + const appInfo = deployer.getApp('crowdFundApproval.teal', 'crowdFundClear.teal'); // get from checkpoint const escrowAccount = await deployer.loadLogic('crowdFundEscrow.py', { APP_ID: appInfo.appID }); // Atomic Transaction (Stateful Smart Contract call + Payment Transaction) diff --git a/examples/crowdfunding/scripts/transfer/delete.js b/examples/crowdfunding/scripts/transfer/delete.js index 8ab05ab01..bb4bf7322 100644 --- a/examples/crowdfunding/scripts/transfer/delete.js +++ b/examples/crowdfunding/scripts/transfer/delete.js @@ -1,5 +1,5 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); @@ -14,14 +14,14 @@ async function run (runtimeEnv, deployer) { payFlags: {} }); - const appInfo = deployer.getSSC('crowdFundApproval.teal', 'crowdFundClear.teal'); + const appInfo = deployer.getApp('crowdFundApproval.teal', 'crowdFundClear.teal'); const lsig = await deployer.loadLogic('crowdFundEscrow.py', { APP_ID: appInfo.appID }); const escrowAccountAddress = lsig.address(); // Atomic Transaction (Stateful Smart Contract call + Payment Transaction) const txGroup = [ { - type: types.TransactionType.DeleteSSC, + type: types.TransactionType.DeleteApp, sign: types.SignType.SecretKey, fromAccount: creatorAccount, appID: appInfo.appID, diff --git a/examples/crowdfunding/scripts/transfer/donate.js b/examples/crowdfunding/scripts/transfer/donate.js index 61d14c1a5..6118ebe25 100644 --- a/examples/crowdfunding/scripts/transfer/donate.js +++ b/examples/crowdfunding/scripts/transfer/donate.js @@ -1,5 +1,5 @@ const { executeTransaction, convert } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); @@ -18,7 +18,7 @@ async function run (runtimeEnv, deployer) { const appArgs = [convert.stringToBytes('donate')]; // Get AppInfo and AssetID from checkpoints. - const appInfo = deployer.getSSC('crowdFundApproval.teal', 'crowdFundClear.teal'); + const appInfo = deployer.getApp('crowdFundApproval.teal', 'crowdFundClear.teal'); // Get Escrow Account Address const escrowAccount = await deployer.loadLogic('crowdFundEscrow.py', { APP_ID: appInfo.appID }); diff --git a/examples/crowdfunding/scripts/transfer/reclaim.js b/examples/crowdfunding/scripts/transfer/reclaim.js index 842e0d397..27187a08f 100644 --- a/examples/crowdfunding/scripts/transfer/reclaim.js +++ b/examples/crowdfunding/scripts/transfer/reclaim.js @@ -1,5 +1,5 @@ const { executeTransaction, convert } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); @@ -18,7 +18,7 @@ async function run (runtimeEnv, deployer) { const appArgs = [convert.stringToBytes('reclaim')]; // Get AppInfo and AssetID from checkpoints. - const appInfo = deployer.getSSC('crowdFundApproval.teal', 'crowdFundClear.teal'); + const appInfo = deployer.getApp('crowdFundApproval.teal', 'crowdFundClear.teal'); // Get Escrow Account Address const lsig = await deployer.loadLogic('crowdFundEscrow.py', { APP_ID: appInfo.appID }); diff --git a/examples/crowdfunding/test/crowdfundingTest.js b/examples/crowdfunding/test/crowdfundingTest.js index 4e7f69dd5..3e24939fb 100644 --- a/examples/crowdfunding/test/crowdfundingTest.js +++ b/examples/crowdfunding/test/crowdfundingTest.js @@ -1,8 +1,8 @@ -const { getProgram } = require('@algo-builder/algob'); +const { getProgram, convert } = require('@algo-builder/algob'); const { - Runtime, AccountStore, types, - uint64ToBigEndian, stringToBytes, addressToPk + Runtime, AccountStore } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { assert } = require('chai'); const minBalance = 10e6; // 10 ALGO's @@ -70,11 +70,11 @@ describe('Crowdfunding Tests', function () { fundCloseDate.setSeconds(fundCloseDate.getSeconds() + 120000); const creationArgs = [ - uint64ToBigEndian(beginDate.getTime()), - uint64ToBigEndian(endDate.getTime()), + convert.uint64ToBigEndian(beginDate.getTime()), + convert.uint64ToBigEndian(endDate.getTime()), `int:${goal}`, // args similar to `goal --app-arg ..` are also supported - addressToPk(creator.address), - uint64ToBigEndian(fundCloseDate.getTime()) + convert.addressToPk(creator.address), + convert.uint64ToBigEndian(fundCloseDate.getTime()) ]; it('crowdfunding application', () => { @@ -94,7 +94,7 @@ describe('Crowdfunding Tests', function () { // create application applicationId = runtime.addApp( { ...creationFlags, appArgs: creationArgs }, {}, approvalProgram, clearProgram); - const creatorPk = addressToPk(creator.address); + const creatorPk = convert.addressToPk(creator.address); // setup escrow account const escrowProg = getProgram('crowdFundEscrow.py', { APP_ID: applicationId }); @@ -127,7 +127,7 @@ describe('Crowdfunding Tests', function () { assert.deepEqual(getGlobal('FundCloseDate'), BigInt(fundCloseDate.getTime())); // update application with correct escrow account address - let appArgs = [addressToPk(escrowAddress)]; // converts algorand address to Uint8Array + let appArgs = [convert.addressToPk(escrowAddress)]; // converts algorand address to Uint8Array runtime.updateApp( creator.address, @@ -135,7 +135,7 @@ describe('Crowdfunding Tests', function () { approvalProgram, clearProgram, {}, { appArgs: appArgs }); - const escrowPk = addressToPk(escrowAddress); + const escrowPk = convert.addressToPk(escrowAddress); // verify escrow storage assert.isDefined(applicationId); @@ -154,7 +154,7 @@ describe('Crowdfunding Tests', function () { // donate correct amount to escrow account // App argument to donate. - appArgs = [stringToBytes('donate')]; + appArgs = [convert.stringToBytes('donate')]; const donationAmount = 600000; // Atomic Transaction (Stateful Smart Contract call + Payment Transaction) let txGroup = [ @@ -184,7 +184,7 @@ describe('Crowdfunding Tests', function () { runtime.setRoundAndTimestamp(5, endDate.getTime() + 12); // donor should be able to reclaim if goal is NOT met and end date is passed - appArgs = [stringToBytes('reclaim')]; + appArgs = [convert.stringToBytes('reclaim')]; // Atomic Transaction (Stateful Smart Contract call + Payment Transaction) txGroup = [ { @@ -219,7 +219,7 @@ describe('Crowdfunding Tests', function () { runtime.setRoundAndTimestamp(5, beginDate.getTime() + 12); // should claim if goal is reached' - appArgs = [stringToBytes('donate')]; + appArgs = [convert.stringToBytes('donate')]; // Atomic Transaction (Stateful Smart Contract call + Payment Transaction) txGroup = [ @@ -247,7 +247,7 @@ describe('Crowdfunding Tests', function () { assert.equal(escrow.balance(), escrowBal + 7000000n); // verify donation of 7000000 runtime.setRoundAndTimestamp(5, endDate.getTime() + 12); - appArgs = [stringToBytes('claim')]; + appArgs = [convert.stringToBytes('claim')]; txGroup = [ { type: types.TransactionType.CallNoOpSSC, @@ -279,7 +279,7 @@ describe('Crowdfunding Tests', function () { // after claiming, creator of the crowdfunding application should be able to delete the application // NOTE: we don't need a txGroup here as escrow is already empty const deleteTx = { - type: types.TransactionType.DeleteSSC, + type: types.TransactionType.DeleteApp, sign: types.SignType.SecretKey, fromAccount: creator.account, appID: applicationId, @@ -318,7 +318,7 @@ describe('Crowdfunding Tests', function () { syncAccounts(); // update application with correct escrow account address - let appArgs = [addressToPk(escrowAddress)]; // converts algorand address to Uint8Array + let appArgs = [convert.addressToPk(escrowAddress)]; // converts algorand address to Uint8Array runtime.updateApp( creator.address, applicationId, @@ -326,7 +326,7 @@ describe('Crowdfunding Tests', function () { clearProgram, {}, { appArgs: appArgs }); - appArgs = [stringToBytes('claim')]; + appArgs = [convert.stringToBytes('claim')]; // Atomic Transaction (Stateful Smart Contract call + Payment Transaction) const txGroup = [ { diff --git a/examples/crowdfunding/test/failing-tests.js b/examples/crowdfunding/test/failing-tests.js index da0b0fe37..cd0572f7a 100644 --- a/examples/crowdfunding/test/failing-tests.js +++ b/examples/crowdfunding/test/failing-tests.js @@ -1,8 +1,8 @@ -const { getProgram } = require('@algo-builder/algob'); +const { getProgram, convert } = require('@algo-builder/algob'); const { - Runtime, AccountStore, types, - uint64ToBigEndian, stringToBytes, addressToPk + Runtime, AccountStore } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { assert } = require('chai'); const minBalance = 10e6; // 10 ALGO's @@ -49,11 +49,11 @@ describe('Crowdfunding Test - Failing Scenarios', function () { runtime.setRoundAndTimestamp(5, beginDate.getTime() + 100); const creationArgs = [ - uint64ToBigEndian(beginDate.getTime()), - uint64ToBigEndian(endDate.getTime()), + convert.uint64ToBigEndian(beginDate.getTime()), + convert.uint64ToBigEndian(endDate.getTime()), `int:${goal}`, // args similar to `goal --app-arg ..` are also supported - addressToPk(creator.address), - uint64ToBigEndian(fundCloseDate.getTime()) + convert.addressToPk(creator.address), + convert.uint64ToBigEndian(fundCloseDate.getTime()) ]; const creationFlags = { sender: creator.account, @@ -86,7 +86,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { payFlags: {} }); - appArgs = [stringToBytes('donate')]; + appArgs = [convert.stringToBytes('donate')]; donateTxGroup = [ { type: types.TransactionType.CallNoOpSSC, @@ -109,7 +109,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { function updateAndOptIn () { // update application with correct escrow account address - appArgs = [addressToPk(escrowAddress)]; // converts algorand address to Uint8Array + appArgs = [convert.addressToPk(escrowAddress)]; // converts algorand address to Uint8Array runtime.updateApp( creator.address, @@ -131,7 +131,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { it('should fail donation if donor has insufficient balance', () => { updateAndOptIn(); - appArgs = [stringToBytes('donate')]; + appArgs = [convert.stringToBytes('donate')]; const donationAmount = initialDonorBalance + 1000; // Atomic Transaction (Stateful Smart Contract call + Payment Transaction) const txGroup = [ @@ -179,7 +179,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { runtime.executeTx(donateTxGroup); runtime.setRoundAndTimestamp(5, endDate.getTime() + 100); // end date is passed - appArgs = [stringToBytes('reclaim')]; + appArgs = [convert.stringToBytes('reclaim')]; // Atomic Transaction (Stateful Smart Contract call + Payment Transaction) const txGroup = [ { @@ -209,7 +209,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { updateAndOptIn(); runtime.executeTx(donateTxGroup); - appArgs = [stringToBytes('reclaim')]; + appArgs = [convert.stringToBytes('reclaim')]; // Atomic Transaction (Stateful Smart Contract call + Payment Transaction) const txGroup = [ { @@ -240,7 +240,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { // set donation to greater than goal donateTxGroup[1].amountMicroAlgos = goal + 1000; runtime.executeTx(donateTxGroup); - appArgs = [stringToBytes('claim')]; + appArgs = [convert.stringToBytes('claim')]; const txGroup = [ { type: types.TransactionType.CallNoOpSSC, @@ -266,7 +266,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { it('should fail if a transaction is missing in group transaction while donating', () => { updateAndOptIn(); - appArgs = [stringToBytes('donate')]; + appArgs = [convert.stringToBytes('donate')]; const txGroup = [ { type: types.TransactionType.CallNoOpSSC, @@ -289,7 +289,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { const escrowProg = getProgram('wrongEscrow.teal', { APP_ID: applicationId }); const wrongLsig = runtime.getLogicSig(escrowProg, []); runtime.setRoundAndTimestamp(5, endDate.getTime() + 11); - appArgs = [stringToBytes('claim')]; + appArgs = [convert.stringToBytes('claim')]; const txGroup = [ { type: types.TransactionType.CallNoOpSSC, @@ -329,7 +329,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { donateTxGroup[1].amountMicroAlgos = goal + 1000; runtime.executeTx(donateTxGroup); runtime.setRoundAndTimestamp(5, endDate.getTime() + 11); - appArgs = [stringToBytes('claim')]; + appArgs = [convert.stringToBytes('claim')]; const txGroup = [ { type: types.TransactionType.CallNoOpSSC, @@ -356,7 +356,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { updateAndOptIn(); runtime.setRoundAndTimestamp(5, fundCloseDate.getTime() + 12); const deleteTx = { - type: types.TransactionType.DeleteSSC, + type: types.TransactionType.DeleteApp, sign: types.SignType.SecretKey, fromAccount: creator.account, appID: applicationId, @@ -369,7 +369,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { }); it('should fail on trying to update application where sender is not creator', () => { - appArgs = [addressToPk(escrowAddress)]; // converts algorand address to Uint8Array + appArgs = [convert.addressToPk(escrowAddress)]; // converts algorand address to Uint8Array assert.throws(() => runtime.updateApp( @@ -389,7 +389,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { donateTxGroup[1].amountMicroAlgos = goal + 1000; runtime.executeTx(donateTxGroup); runtime.setRoundAndTimestamp(5, endDate.getTime() + 122); - appArgs = [stringToBytes('claim')]; + appArgs = [convert.stringToBytes('claim')]; const txGroup = [ { type: types.TransactionType.CallNoOpSSC, @@ -422,7 +422,7 @@ describe('Crowdfunding Test - Failing Scenarios', function () { donateTxGroup[1].amountMicroAlgos = goal + 1000; runtime.executeTx(donateTxGroup); runtime.setRoundAndTimestamp(5, endDate.getTime() + 122); - appArgs = [stringToBytes('claim')]; + appArgs = [convert.stringToBytes('claim')]; const txGroup = [ { type: types.TransactionType.CallNoOpSSC, diff --git a/examples/crowdfunding/test/happypaths.js b/examples/crowdfunding/test/happypaths.js index d65f5c624..5da4d450f 100644 --- a/examples/crowdfunding/test/happypaths.js +++ b/examples/crowdfunding/test/happypaths.js @@ -1,8 +1,8 @@ -const { getProgram } = require('@algo-builder/algob'); +const { getProgram, convert } = require('@algo-builder/algob'); const { - Runtime, AccountStore, types, - uint64ToBigEndian, stringToBytes, addressToPk + Runtime, AccountStore } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { assert } = require('chai'); const minBalance = 10e6; // 10 ALGO's @@ -69,11 +69,11 @@ describe('Crowdfunding Tests - Happy Paths', function () { runtime.store.globalApps.set(applicationId, creator.address); // set creation args in global state - creator.setGlobalState(applicationId, 'Creator', addressToPk(creator.address)); + creator.setGlobalState(applicationId, 'Creator', convert.addressToPk(creator.address)); creator.setGlobalState(applicationId, 'StartDate', 1n); creator.setGlobalState(applicationId, 'EndDate', 10n); creator.setGlobalState(applicationId, 'Goal', BigInt(goal)); - creator.setGlobalState(applicationId, 'Receiver', addressToPk(fundReceiver.address)); + creator.setGlobalState(applicationId, 'Receiver', convert.addressToPk(fundReceiver.address)); creator.setGlobalState(applicationId, 'Total', 0n); creator.setGlobalState(applicationId, 'FundCloseDate', 20n); @@ -98,20 +98,20 @@ describe('Crowdfunding Tests - Happy Paths', function () { const beginTs = 1n; // fund begin timestamp const endTs = 10n; // fund end timestamp const fundCloseTs = 20n; // fund close timestamp - const fundReceiverPk = addressToPk(fundReceiver.address); + const fundReceiverPk = convert.addressToPk(fundReceiver.address); const creationArgs = [ - uint64ToBigEndian(beginTs), - uint64ToBigEndian(endTs), + convert.uint64ToBigEndian(beginTs), + convert.uint64ToBigEndian(endTs), `int:${goal}`, // args similar to `goal --app-arg ..` are also supported fundReceiverPk, - uint64ToBigEndian(fundCloseTs) + convert.uint64ToBigEndian(fundCloseTs) ]; // create application applicationId = runtime.addApp( { ...creationFlags, appArgs: creationArgs }, {}, approvalProgram, clearProgram); - const creatorPk = addressToPk(creator.address); + const creatorPk = convert.addressToPk(creator.address); assert.isDefined(applicationId); assert.deepEqual(getGlobal('Creator'), creatorPk); @@ -126,7 +126,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { it('should setup escrow account and update application with escrow address', () => { setupAppAndEscrow(); - const escrowPk = addressToPk(escrow.address); + const escrowPk = convert.addressToPk(escrow.address); runtime.updateApp( creator.address, applicationId, @@ -145,7 +145,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { setupAppAndEscrow(); // update global storage to add escrow address - const escrowPk = addressToPk(escrow.address); + const escrowPk = convert.addressToPk(escrow.address); creator.setGlobalState(applicationId, 'Escrow', escrowPk); runtime.optInToApp(creator.address, applicationId, {}, {}); @@ -162,7 +162,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { runtime.setRoundAndTimestamp(2, 5); // StartTs=1, EndTs=10 // update global storage to add escrow address - const escrowPk = addressToPk(escrow.address); + const escrowPk = convert.addressToPk(escrow.address); runtime.getAccount(creator.address).setGlobalState(applicationId, 'Escrow', escrowPk); syncAccounts(); @@ -181,7 +181,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { fromAccount: donor.account, appID: applicationId, payFlags: { totalFee: 1000 }, - appArgs: [stringToBytes('donate')] + appArgs: [convert.stringToBytes('donate')] }, { type: types.TransactionType.TransferAlgo, @@ -204,7 +204,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { setupAppAndEscrow(); // fund end date should be passed runtime.setRoundAndTimestamp(2, 15); // StartTs=1, EndTs=10 - runtime.getAccount(creator.address).setGlobalState(applicationId, 'Escrow', addressToPk(escrow.address)); + runtime.getAccount(creator.address).setGlobalState(applicationId, 'Escrow', convert.addressToPk(escrow.address)); syncAccounts(); creator.optInToApp(applicationId, runtime.getApp(applicationId)); @@ -235,7 +235,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { fromAccount: creator.account, appID: applicationId, payFlags: { totalFee: 1000 }, - appArgs: [stringToBytes('claim')] + appArgs: [convert.stringToBytes('claim')] }, { type: types.TransactionType.TransferAlgo, @@ -258,7 +258,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { setupAppAndEscrow(); // fund end date should be passed runtime.setRoundAndTimestamp(2, 15); // StartTs=1, EndTs=10 - runtime.getAccount(creator.address).setGlobalState(applicationId, 'Escrow', addressToPk(escrow.address)); + runtime.getAccount(creator.address).setGlobalState(applicationId, 'Escrow', convert.addressToPk(escrow.address)); syncAccounts(); creator.optInToApp(applicationId, runtime.getApp(applicationId)); @@ -289,7 +289,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { fromAccount: donor.account, appID: applicationId, payFlags: { totalFee: 1000 }, - appArgs: [stringToBytes('reclaim')], + appArgs: [convert.stringToBytes('reclaim')], accounts: [escrow.address] // AppAccounts }, { @@ -316,7 +316,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { setupAppAndEscrow(); // fund close date should be passed runtime.setRoundAndTimestamp(2, 25); // fundCloseTs=20n - runtime.getAccount(creator.address).setGlobalState(applicationId, 'Escrow', addressToPk(escrow.address)); + runtime.getAccount(creator.address).setGlobalState(applicationId, 'Escrow', convert.addressToPk(escrow.address)); syncAccounts(); creator.optInToApp(applicationId, runtime.getApp(applicationId)); @@ -336,7 +336,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { // escrow is already empty so we don't need a tx group const deleteTx = { - type: types.TransactionType.DeleteSSC, + type: types.TransactionType.DeleteApp, sign: types.SignType.SecretKey, fromAccount: creator.account, appID: applicationId, @@ -363,7 +363,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { setupAppAndEscrow(); // fund close date should be passed runtime.setRoundAndTimestamp(2, 25); // fundCloseTs=20n - runtime.getAccount(creator.address).setGlobalState(applicationId, 'Escrow', addressToPk(escrow.address)); + runtime.getAccount(creator.address).setGlobalState(applicationId, 'Escrow', convert.addressToPk(escrow.address)); syncAccounts(); creator.optInToApp(applicationId, runtime.getApp(applicationId)); @@ -374,7 +374,7 @@ describe('Crowdfunding Tests - Happy Paths', function () { // where in the second tx, we empty the escrow account to receiver using closeRemainderTo const deleteTxGroup = [ { - type: types.TransactionType.DeleteSSC, + type: types.TransactionType.DeleteApp, sign: types.SignType.SecretKey, fromAccount: creator.account, appID: applicationId, diff --git a/examples/htlc-pyteal-ts/scripts/deploy.ts b/examples/htlc-pyteal-ts/scripts/deploy.ts index f5aefeb53..588769233 100644 --- a/examples/htlc-pyteal-ts/scripts/deploy.ts +++ b/examples/htlc-pyteal-ts/scripts/deploy.ts @@ -3,7 +3,7 @@ * This file demonstrates the PyTeal Example for HTLC(Hash Time Lock Contract) */ import * as algob from "@algo-builder/algob"; -import { types as rtypes } from "@algo-builder/runtime"; +import { types as rtypes } from "@algo-builder/web"; import { getDeployerAccount, prepareParameters } from "./withdraw/common"; diff --git a/examples/htlc-pyteal-ts/scripts/withdraw/common.ts b/examples/htlc-pyteal-ts/scripts/withdraw/common.ts index 9d1d446e1..a89b8c44c 100644 --- a/examples/htlc-pyteal-ts/scripts/withdraw/common.ts +++ b/examples/htlc-pyteal-ts/scripts/withdraw/common.ts @@ -1,6 +1,7 @@ import { executeTransaction } from "@algo-builder/algob"; import * as algob from "@algo-builder/algob"; import { types as rtypes } from "@algo-builder/runtime"; +import { types as wtypes } from "@algo-builder/web"; import { sha256 } from 'js-sha256'; /** @@ -18,7 +19,7 @@ export function getDeployerAccount ( } export async function executeTx ( - deployer: algob.types.Deployer, txnParams: rtypes.ExecParams): Promise { + deployer: algob.types.Deployer, txnParams: wtypes.ExecParams): Promise { try { await executeTransaction(deployer, txnParams); } catch (e) { diff --git a/examples/htlc-pyteal-ts/scripts/withdraw/htlc-withdraw.ts b/examples/htlc-pyteal-ts/scripts/withdraw/htlc-withdraw.ts index f17330205..30d0ae766 100644 --- a/examples/htlc-pyteal-ts/scripts/withdraw/htlc-withdraw.ts +++ b/examples/htlc-pyteal-ts/scripts/withdraw/htlc-withdraw.ts @@ -7,7 +7,7 @@ * if the seller is able to provide the secret value that corresponds to the hash in the program. */ import * as algob from "@algo-builder/algob"; -import { types as rtypes } from "@algo-builder/runtime"; +import { types as rtypes } from "@algo-builder/web"; import { executeTx, prepareParameters } from "./common"; diff --git a/examples/multisig/scripts/multisig_goal_sc.js b/examples/multisig/scripts/multisig_goal_sc.js index c007fd337..704d7de78 100644 --- a/examples/multisig/scripts/multisig_goal_sc.js +++ b/examples/multisig/scripts/multisig_goal_sc.js @@ -6,7 +6,7 @@ */ const { executeTransaction } = require('./common/common'); const { createMsigAddress } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); diff --git a/examples/multisig/scripts/multisig_sdk_sc.js b/examples/multisig/scripts/multisig_sdk_sc.js index 02a984793..25e7c1961 100644 --- a/examples/multisig/scripts/multisig_sdk_sc.js +++ b/examples/multisig/scripts/multisig_sdk_sc.js @@ -5,7 +5,7 @@ */ const { executeTransaction } = require('./common/common'); const { createMsigAddress, signLogicSigMultiSig } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); diff --git a/examples/nft/scripts/deploy-nft.js b/examples/nft/scripts/deploy-nft.js index 0bb9c4f21..f080468c6 100644 --- a/examples/nft/scripts/deploy-nft.js +++ b/examples/nft/scripts/deploy-nft.js @@ -2,7 +2,7 @@ * Description: * This file deploys the stateful smart contract to create and transfer NFT */ -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { executeTransaction } = require('./transfer/common'); async function run (runtimeEnv, deployer) { @@ -20,20 +20,20 @@ async function run (runtimeEnv, deployer) { await executeTransaction(deployer, algoTxnParams); // fund john - await deployer.deploySSC('nft_approval.py', 'nft_clear_state.py', { + await deployer.deployApp('nft_approval.py', 'nft_clear_state.py', { sender: masterAccount, localInts: 16, globalInts: 1, globalBytes: 63 }, {}); - const sscInfo = await deployer.getSSC('nft_approval.py', 'nft_clear_state.py'); - const appID = sscInfo.appID; - console.log(sscInfo); + const appInfo = await deployer.getApp('nft_approval.py', 'nft_clear_state.py'); + const appID = appInfo.appID; + console.log(appInfo); try { - await deployer.optInAccountToSSC(masterAccount, appID, {}, {}); // opt-in to asc by master - await deployer.optInAccountToSSC(john, appID, {}, {}); // opt-in to asc by john + await deployer.optInAccountToApp(masterAccount, appID, {}, {}); // opt-in to asc by master + await deployer.optInAccountToApp(john, appID, {}, {}); // opt-in to asc by john } catch (e) { console.log(e); throw new Error(e); diff --git a/examples/nft/scripts/transfer/create-transfer-nft.js b/examples/nft/scripts/transfer/create-transfer-nft.js index f3360503f..f696b69dd 100644 --- a/examples/nft/scripts/transfer/create-transfer-nft.js +++ b/examples/nft/scripts/transfer/create-transfer-nft.js @@ -4,15 +4,15 @@ */ const { executeTransaction, printGlobalNFT, printLocalNFT } = require('./common'); const { convert } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); const john = deployer.accountsByName.get('john'); - const sscInfo = await deployer.getSSC('nft_approval.py', 'nft_clear_state.py'); - const appID = sscInfo.appID; - console.log(sscInfo); + const appInfo = await deployer.getApp('nft_approval.py', 'nft_clear_state.py'); + const appID = appInfo.appID; + console.log(appInfo); await printGlobalNFT(deployer, masterAccount.addr, appID); // Global Count before creation diff --git a/examples/permissioned-token-freezing/scripts/0-createAppAsset.js b/examples/permissioned-token-freezing/scripts/0-createAppAsset.js index cfb2b70a6..e3e2141ce 100644 --- a/examples/permissioned-token-freezing/scripts/0-createAppAsset.js +++ b/examples/permissioned-token-freezing/scripts/0-createAppAsset.js @@ -1,7 +1,7 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const master = deployer.accountsByName.get('master-account'); @@ -32,7 +32,7 @@ async function run (runtimeEnv, deployer) { 'int:2' // set min user level(2) for asset transfer ("Accred-level") ]; - const sscInfo = await deployer.deploySSC( + const sscInfo = await deployer.deployApp( 'poi-approval.teal', // approval program 'poi-clear.teal', // clear program { @@ -49,8 +49,8 @@ async function run (runtimeEnv, deployer) { const appID = sscInfo.appID; console.log('Opting-In for Creator(Alice) and Bob.'); try { - await deployer.optInAccountToSSC(creator, appID, {}, {}); - await deployer.optInAccountToSSC(bob, appID, {}, {}); + await deployer.optInAccountToApp(creator, appID, {}, {}); + await deployer.optInAccountToApp(bob, appID, {}, {}); } catch (e) { console.log(e); throw new Error(e); diff --git a/examples/permissioned-token-freezing/scripts/1-assetConfig.js b/examples/permissioned-token-freezing/scripts/1-assetConfig.js index ca6b46a8b..33dd2592f 100644 --- a/examples/permissioned-token-freezing/scripts/1-assetConfig.js +++ b/examples/permissioned-token-freezing/scripts/1-assetConfig.js @@ -1,13 +1,13 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const creator = deployer.accountsByName.get('alice'); // NOTE: make sure to deploy 0-createAppAsset.js first - const appInfo = deployer.getSSC('poi-approval.teal', 'poi-clear.teal'); + const appInfo = deployer.getApp('poi-approval.teal', 'poi-clear.teal'); const assetInfo = deployer.asa.get('gold'); /** * Compile and fund escrow***/ diff --git a/examples/permissioned-token-freezing/scripts/transfer/set-clear-level.js b/examples/permissioned-token-freezing/scripts/transfer/set-clear-level.js index 0c7989b5f..7d1929e43 100644 --- a/examples/permissioned-token-freezing/scripts/transfer/set-clear-level.js +++ b/examples/permissioned-token-freezing/scripts/transfer/set-clear-level.js @@ -1,5 +1,5 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const creator = deployer.accountsByName.get('alice'); @@ -9,7 +9,7 @@ async function run (runtimeEnv, deployer) { * Set level:2 for Alice and Bob (required by smart-contract for asset transfer) * level refers to the minimum required level of user to transfer an asset */ - const appInfo = deployer.getSSC('poi-approval.teal', 'poi-clear.teal'); + const appInfo = deployer.getApp('poi-approval.teal', 'poi-clear.teal'); const setLevelParams = { type: types.TransactionType.CallNoOpSSC, sign: types.SignType.SecretKey, diff --git a/examples/permissioned-token-freezing/scripts/transfer/transfer-asset.js b/examples/permissioned-token-freezing/scripts/transfer/transfer-asset.js index e57284342..d5b2636b3 100644 --- a/examples/permissioned-token-freezing/scripts/transfer/transfer-asset.js +++ b/examples/permissioned-token-freezing/scripts/transfer/transfer-asset.js @@ -1,12 +1,12 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const creator = deployer.accountsByName.get('alice'); const bob = deployer.accountsByName.get('bob'); // NOTE: set min asset level first using ./set-clear-level.js - const appInfo = deployer.getSSC('poi-approval.teal', 'poi-clear.teal'); + const appInfo = deployer.getApp('poi-approval.teal', 'poi-clear.teal'); const assetInfo = deployer.asa.get('gold'); const escrowParams = { diff --git a/examples/permissioned-token-freezing/test/asset-txfer-test.js b/examples/permissioned-token-freezing/test/asset-txfer-test.js index 36a7ad729..14e41dd95 100644 --- a/examples/permissioned-token-freezing/test/asset-txfer-test.js +++ b/examples/permissioned-token-freezing/test/asset-txfer-test.js @@ -1,6 +1,7 @@ -import { getProgram } from '@algo-builder/algob'; -import { AccountStore, addressToPk, Runtime, types } from '@algo-builder/runtime'; +import { convert, getProgram } from '@algo-builder/algob'; +import { AccountStore, Runtime } from '@algo-builder/runtime'; import { assert } from 'chai'; +const { types } = require('@algo-builder/web'); const minBalance = 10e6; // 10 ALGO's const aliceAddr = 'EDXG4GGBEHFLNX6A7FGT3F6Z3TQGIU6WVVJNOXGYLVNTLWDOCEJJ35LWJY'; @@ -61,7 +62,7 @@ describe('Test for transferring asset using custom logic', function () { { ...creationFlags, appArgs: creationArgs }, {}, approvalProgram, clearProgram); const app = alice.getApp(applicationId); - const alicePk = addressToPk(alice.address); + const alicePk = convert.addressToPk(alice.address); // verify global state after app creation assert.isDefined(app); diff --git a/examples/permissioned-token/assets/controller.py b/examples/permissioned-token/assets/controller.py index 5ccd9815b..76bfe6e89 100644 --- a/examples/permissioned-token/assets/controller.py +++ b/examples/permissioned-token/assets/controller.py @@ -181,7 +181,7 @@ def approval_program(TOKEN_ID): # Verifies that DeleteApplication is used and blocks that call # Verifies that UpdateApplication is used and blocks that call (unsafe for production use). # Verifies that closeOut is used and approves the tx. - # Verifies that OptInApplication is used and jumps to handle_optin + # Verifies that OptInToApplication is used and jumps to handle_optin # Verifies that first argument is "set_permission" and jumps to set_permission_contract. # Verifies that first argument is "issue" and jumps to issue. # Verifies that first argument is "kill" and jumps to kill. diff --git a/examples/permissioned-token/assets/permissions.py b/examples/permissioned-token/assets/permissions.py index 3679b214d..50b7d586f 100644 --- a/examples/permissioned-token/assets/permissions.py +++ b/examples/permissioned-token/assets/permissions.py @@ -152,7 +152,7 @@ def approval_program(PERM_MANAGER): # Verifies that DeleteApplication is used and blocks that call # Verifies that UpdateApplication is used and jumps to handle_update. # Verifies that closeOut is used and approves the tx. - # Verifies that OptInApplication is used and jumps to handle_optin + # Verifies that OptInToApplication is used and jumps to handle_optin # Verifies that first argument is "change_permissions_manager" and jumps to change_permissions_manager. # Verifies that first argument is "add_whitelist" and jumps to add_whitelist. # Verifies that first argument is "transfer" and jumps to transfer_token. diff --git a/examples/permissioned-token/scripts/1-setup-controller.js b/examples/permissioned-token/scripts/1-setup-controller.js index 2b3d73a95..bb0781eba 100644 --- a/examples/permissioned-token/scripts/1-setup-controller.js +++ b/examples/permissioned-token/scripts/1-setup-controller.js @@ -19,7 +19,7 @@ async function setupControllerSSC (runtimeEnv, deployer) { }; console.log('\n** Deploying smart contract: controller **'); - const controllerSSCInfo = await deployer.deploySSC( + const controllerSSCInfo = await deployer.deployApp( 'controller.py', // approval program 'clear_state_program.py', // clear program { diff --git a/examples/permissioned-token/scripts/2-asset-clawback.js b/examples/permissioned-token/scripts/2-asset-clawback.js index 21bfca75c..9569e0444 100644 --- a/examples/permissioned-token/scripts/2-asset-clawback.js +++ b/examples/permissioned-token/scripts/2-asset-clawback.js @@ -1,7 +1,7 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const accounts = require('./common/accounts'); const { getClawbackParams, getClawback } = require('./common/common'); diff --git a/examples/permissioned-token/scripts/3-setup-permissions.js b/examples/permissioned-token/scripts/3-setup-permissions.js index e819ed4fc..efcbf187f 100644 --- a/examples/permissioned-token/scripts/3-setup-permissions.js +++ b/examples/permissioned-token/scripts/3-setup-permissions.js @@ -1,7 +1,7 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const accounts = require('./common/accounts'); /** @@ -9,7 +9,7 @@ const accounts = require('./common/accounts'); * and link it to the controller (using the controller add_permission argument) */ async function setupPermissionsApp (runtimeEnv, deployer) { - const controllerSSCInfo = deployer.getSSC('controller.py', 'clear_state_program.py'); + const controllerSSCInfo = deployer.getApp('controller.py', 'clear_state_program.py'); const tesla = deployer.asa.get('tesla'); const owner = deployer.accountsByName.get(accounts.owner); @@ -21,7 +21,7 @@ async function setupPermissionsApp (runtimeEnv, deployer) { /** Deploy Permissions(rules) smart contract **/ console.log('\n** Deploying smart contract: permissions **'); - const permissionSSCInfo = await deployer.deploySSC( + const permissionSSCInfo = await deployer.deployApp( 'permissions.py', // approval program 'clear_state_program.py', // clear program { diff --git a/examples/permissioned-token/scripts/admin/force-transfer.js b/examples/permissioned-token/scripts/admin/force-transfer.js index 3a21c94aa..d2ddf5790 100644 --- a/examples/permissioned-token/scripts/admin/force-transfer.js +++ b/examples/permissioned-token/scripts/admin/force-transfer.js @@ -1,10 +1,10 @@ const { balanceOf, executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const accounts = require('../common/accounts'); -const { getClawback, fundAccount, optInAccountToSSC } = require('../common/common'); +const { getClawback, fundAccount, optInAccountToApp } = require('../common/common'); const { issue } = require('./issue'); const { whitelist } = require('../permissions/whitelist'); @@ -19,8 +19,8 @@ const clearStateProgram = 'clear_state_program.py'; async function forceTransfer (deployer, fromAddr, toAddr, amount) { const owner = deployer.accountsByName.get(accounts.owner); const tesla = deployer.asa.get('tesla'); - const controllerSSCInfo = deployer.getSSC('controller.py', clearStateProgram); - const permissionsSSCInfo = deployer.getSSC('permissions.py', clearStateProgram); + const controllerSSCInfo = deployer.getApp('controller.py', clearStateProgram); + const permissionsSSCInfo = deployer.getApp('permissions.py', clearStateProgram); const clawbackLsig = await getClawback(deployer); const clawbackAddress = clawbackLsig.address(); @@ -96,7 +96,7 @@ async function forceTransfer (deployer, fromAddr, toAddr, amount) { async function run (runtimeEnv, deployer) { const owner = deployer.accountsByName.get(accounts.owner); const permissionsManager = owner; - const permissionsSSCInfo = deployer.getSSC('permissions.py', clearStateProgram); + const permissionsSSCInfo = deployer.getApp('permissions.py', clearStateProgram); /** * Force transfer some tokens b/w 2 accounts @@ -110,9 +110,9 @@ async function run (runtimeEnv, deployer) { // opt-in accounts to permissions smart contract // comment this code if already opted-in await Promise.all([ - optInAccountToSSC(deployer, elon, permissionsSSCInfo.appID, {}, {}), - optInAccountToSSC(deployer, bob, permissionsSSCInfo.appID, {}, {}), - optInAccountToSSC(deployer, john, permissionsSSCInfo.appID, {}, {}) + optInAccountToApp(deployer, elon, permissionsSSCInfo.appID, {}, {}), + optInAccountToApp(deployer, bob, permissionsSSCInfo.appID, {}, {}), + optInAccountToApp(deployer, john, permissionsSSCInfo.appID, {}, {}) ]); /* diff --git a/examples/permissioned-token/scripts/admin/issue.js b/examples/permissioned-token/scripts/admin/issue.js index a6c7f98c1..f82c87975 100644 --- a/examples/permissioned-token/scripts/admin/issue.js +++ b/examples/permissioned-token/scripts/admin/issue.js @@ -1,7 +1,7 @@ const { balanceOf } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { getClawback, executeTransaction, fundAccount, totalSupply } = require('../common/common'); const accounts = require('../common/accounts'); @@ -11,7 +11,7 @@ const accounts = require('../common/accounts'); async function issue (deployer, address, amount) { const issuer = deployer.accountsByName.get(accounts.issuer); const tesla = deployer.asa.get('tesla'); - const controllerSSCInfo = deployer.getSSC('controller.py', 'clear_state_program.py'); + const controllerSSCInfo = deployer.getApp('controller.py', 'clear_state_program.py'); const clawbackLsig = await getClawback(deployer); const clawbackAddress = clawbackLsig.address(); diff --git a/examples/permissioned-token/scripts/admin/kill.js b/examples/permissioned-token/scripts/admin/kill.js index 112cd6a35..ae6fb5bd8 100644 --- a/examples/permissioned-token/scripts/admin/kill.js +++ b/examples/permissioned-token/scripts/admin/kill.js @@ -1,4 +1,4 @@ -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { issue } = require('./issue'); const { executeTransaction, fundAccount } = require('../common/common'); const accounts = require('../common/accounts'); @@ -14,7 +14,7 @@ async function kill (deployer) { * token is killed. */ const tesla = deployer.asa.get('tesla'); - const controllerSSCInfo = deployer.getSSC('controller.py', 'clear_state_program.py'); + const controllerSSCInfo = deployer.getApp('controller.py', 'clear_state_program.py'); const killParams = { type: types.TransactionType.CallNoOpSSC, sign: types.SignType.SecretKey, diff --git a/examples/permissioned-token/scripts/admin/update-reserve.js b/examples/permissioned-token/scripts/admin/update-reserve.js index e05d4cefb..3950202a1 100644 --- a/examples/permissioned-token/scripts/admin/update-reserve.js +++ b/examples/permissioned-token/scripts/admin/update-reserve.js @@ -1,7 +1,7 @@ const { balanceOf } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { getClawback, executeTransaction, fundAccount } = require('../common/common'); const accounts = require('../common/accounts'); @@ -31,7 +31,7 @@ async function updateReserveByAssetConfig (deployer, address) { // fetch old asset reserve from network by assetId const tesla = deployer.asa.get('tesla'); const asaReserveAddr = (await deployer.getAssetByID(tesla.assetIndex)).params.reserve; - const controllerSSCInfo = deployer.getSSC('controller.py', 'clear_state_program.py'); + const controllerSSCInfo = deployer.getApp('controller.py', 'clear_state_program.py'); const clawbackLsig = await getClawback(deployer); const clawbackAddress = clawbackLsig.address(); diff --git a/examples/permissioned-token/scripts/common/common.js b/examples/permissioned-token/scripts/common/common.js index 5995a7f41..3227d046f 100644 --- a/examples/permissioned-token/scripts/common/common.js +++ b/examples/permissioned-token/scripts/common/common.js @@ -1,5 +1,5 @@ const { executeTransaction, balanceOf } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); exports.executeTransaction = async function (deployer, txnParams) { try { @@ -39,12 +39,12 @@ exports.fundAccount = async function (deployer, account) { } }; -exports.optInAccountToSSC = async function (deployer, account, appID, payflags, sscOptionalFlags) { +exports.optInAccountToApp = async function (deployer, account, appID, payflags, AppOptionalFlags) { try { console.log(`* Opting In: ${account.name} to SSC with application index: ${appID} *`); - await deployer.optInAccountToSSC(account, appID, payflags, sscOptionalFlags); + await deployer.optInAccountToApp(account, appID, payflags, AppOptionalFlags); } catch (e) { - console.error('optInAccountToSSC failed', e.response?.error); // probably app already optedIn + console.error('optInAccountToApp failed', e.response?.error); // probably app already optedIn } }; @@ -57,7 +57,7 @@ exports.totalSupply = async function (deployer, assetIndex) { function getClawbackParams (deployer) { const tesla = deployer.asa.get('tesla'); - const controllerInfo = deployer.getSSC('controller.py', 'clear_state_program.py'); + const controllerInfo = deployer.getApp('controller.py', 'clear_state_program.py'); return { TOKEN_ID: tesla.assetIndex, CONTROLLER_APP_ID: controllerInfo.appID diff --git a/examples/permissioned-token/scripts/permissions/change-perm-manager.js b/examples/permissioned-token/scripts/permissions/change-perm-manager.js index c8865cf23..93345a77f 100644 --- a/examples/permissioned-token/scripts/permissions/change-perm-manager.js +++ b/examples/permissioned-token/scripts/permissions/change-perm-manager.js @@ -1,6 +1,6 @@ -const { fundAccount, executeTransaction, optInAccountToSSC } = require('../common/common'); +const { fundAccount, executeTransaction, optInAccountToApp } = require('../common/common'); const { whitelist } = require('./whitelist'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const accounts = require('../common/accounts'); /** @@ -9,7 +9,7 @@ const accounts = require('../common/accounts'); * @param address account address to change permissions_manager to */ async function changePermissionsManager (deployer, permissionsManager, address) { - const permissionSSCInfo = deployer.getSSC('permissions.py', 'clear_state_program.py'); + const permissionSSCInfo = deployer.getApp('permissions.py', 'clear_state_program.py'); const changePerManagerParams = { type: types.TransactionType.CallNoOpSSC, @@ -35,8 +35,8 @@ async function run (runtimeEnv, deployer) { await fundAccount(deployer, [permissionsManager, elon]); console.log('* Opt-In to permissions(rules) smart contract *'); - const permissionSSCInfo = deployer.getSSC('permissions.py', 'clear_state_program.py'); - await optInAccountToSSC(deployer, elon, permissionSSCInfo.appID, {}, {}); + const permissionSSCInfo = deployer.getApp('permissions.py', 'clear_state_program.py'); + await optInAccountToApp(deployer, elon, permissionSSCInfo.appID, {}, {}); // tx FAIL because john is not a permissions manager try { diff --git a/examples/permissioned-token/scripts/permissions/whitelist.js b/examples/permissioned-token/scripts/permissions/whitelist.js index 6171e78eb..32d41423a 100644 --- a/examples/permissioned-token/scripts/permissions/whitelist.js +++ b/examples/permissioned-token/scripts/permissions/whitelist.js @@ -1,8 +1,8 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { fundAccount, optInAccountToSSC } = require('../common/common'); -const { types } = require('@algo-builder/runtime'); +const { fundAccount, optInAccountToApp } = require('../common/common'); +const { types } = require('@algo-builder/web'); const accounts = require('../common/accounts'); const clearStateProgram = 'clear_state_program.py'; @@ -18,7 +18,7 @@ const clearStateProgram = 'clear_state_program.py'; * @param address account address to whitelist */ async function whitelist (deployer, permissionsManager, address) { - const permissionSSCInfo = deployer.getSSC('permissions.py', clearStateProgram); + const permissionSSCInfo = deployer.getApp('permissions.py', clearStateProgram); /** * - Only permissions manager can add accounts to whitelist. Which is set to alice(during deploy). @@ -47,13 +47,13 @@ async function run (runtimeEnv, deployer) { const owner = deployer.accountsByName.get(accounts.owner); // alice is set as the permissions_manager during deploy const elon = deployer.accountsByName.get('elon-musk'); const john = deployer.accountsByName.get('john'); - const permissionSSCInfo = deployer.getSSC('permissions.py', clearStateProgram); + const permissionSSCInfo = deployer.getApp('permissions.py', clearStateProgram); /** Fund all accounts with ALGO **/ await fundAccount(deployer, [owner, elon, john]); console.log('* Opt-In and whitelist Elon *'); - await optInAccountToSSC(deployer, elon, permissionSSCInfo.appID, {}, {}); + await optInAccountToApp(deployer, elon, permissionSSCInfo.appID, {}, {}); await whitelist(deployer, owner, elon.addr); // Example of invalid transaction: sender !== permissions manager diff --git a/examples/permissioned-token/scripts/user/opt-out.js b/examples/permissioned-token/scripts/user/opt-out.js index 687957ad5..9ecc455f1 100644 --- a/examples/permissioned-token/scripts/user/opt-out.js +++ b/examples/permissioned-token/scripts/user/opt-out.js @@ -1,7 +1,7 @@ const { balanceOf } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { issue } = require('../admin/issue'); const { executeTransaction, fundAccount } = require('../common/common'); diff --git a/examples/permissioned-token/scripts/user/transfer.js b/examples/permissioned-token/scripts/user/transfer.js index 51f1e19fb..7d71f1007 100644 --- a/examples/permissioned-token/scripts/user/transfer.js +++ b/examples/permissioned-token/scripts/user/transfer.js @@ -1,11 +1,11 @@ const { balanceOf, executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { issue } = require('../admin/issue'); const { whitelist } = require('../permissions/whitelist'); -const { getClawback, fundAccount, optInAccountToSSC } = require('../common/common'); +const { getClawback, fundAccount, optInAccountToApp } = require('../common/common'); const clearStateProgram = 'clear_state_program.py'; /** @@ -16,8 +16,8 @@ const clearStateProgram = 'clear_state_program.py'; */ async function transfer (deployer, from, toAddr, amount) { const tesla = deployer.asa.get('tesla'); - const controllerSSCInfo = deployer.getSSC('controller.py', clearStateProgram); - const permissionsSSCInfo = deployer.getSSC('permissions.py', clearStateProgram); + const controllerSSCInfo = deployer.getApp('controller.py', clearStateProgram); + const permissionsSSCInfo = deployer.getApp('permissions.py', clearStateProgram); const clawbackLsig = await getClawback(deployer); const clawbackAddress = clawbackLsig.address(); @@ -90,7 +90,7 @@ async function transfer (deployer, from, toAddr, amount) { async function run (runtimeEnv, deployer) { // alice is set-up as the permissions manager during deploy const permissionsManager = deployer.accountsByName.get('alice'); - const permissionsSSCInfo = deployer.getSSC('permissions.py', clearStateProgram); + const permissionsSSCInfo = deployer.getApp('permissions.py', clearStateProgram); /* * Transfer some tokens b/w 2 non-reserve accounts @@ -111,9 +111,9 @@ async function run (runtimeEnv, deployer) { // opt-in accounts to permissions smart contract // comment this code if already opted-in await Promise.all([ - optInAccountToSSC(deployer, elon, permissionsSSCInfo.appID, {}, {}), - optInAccountToSSC(deployer, bob, permissionsSSCInfo.appID, {}, {}), - optInAccountToSSC(deployer, john, permissionsSSCInfo.appID, {}, {}) + optInAccountToApp(deployer, elon, permissionsSSCInfo.appID, {}, {}), + optInAccountToApp(deployer, bob, permissionsSSCInfo.appID, {}, {}), + optInAccountToApp(deployer, john, permissionsSSCInfo.appID, {}, {}) ]); /* diff --git a/examples/permissioned-token/test/common.js b/examples/permissioned-token/test/common.js index 1ab89727e..d554645e4 100644 --- a/examples/permissioned-token/test/common.js +++ b/examples/permissioned-token/test/common.js @@ -1,7 +1,8 @@ const { getProgram } = require('@algo-builder/algob'); -const { Runtime, types } = require('@algo-builder/runtime'); +const { Runtime } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const minBalance = 20e6; // 20 ALGOs const CLAWBACK_STATELESS_PROGRAM = 'clawback.py'; diff --git a/examples/permissioned-token/test/failing-paths.js b/examples/permissioned-token/test/failing-paths.js index c6e806949..81cfc9585 100644 --- a/examples/permissioned-token/test/failing-paths.js +++ b/examples/permissioned-token/test/failing-paths.js @@ -1,4 +1,5 @@ -const { types, AccountStore } = require('@algo-builder/runtime'); +const { AccountStore } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { assert } = require('chai'); const { encodeAddress } = require('algosdk'); const { Context } = require('./common'); diff --git a/examples/permissioned-token/test/happy-paths.js b/examples/permissioned-token/test/happy-paths.js index b50872e82..892f0aa59 100644 --- a/examples/permissioned-token/test/happy-paths.js +++ b/examples/permissioned-token/test/happy-paths.js @@ -1,4 +1,5 @@ -const { types, AccountStore } = require('@algo-builder/runtime'); +const { AccountStore } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { encodeAddress } = require('algosdk'); const { assert } = require('chai'); const { Context } = require('./common'); diff --git a/examples/permissioned-voting/scripts/vote/result.js b/examples/permissioned-voting/scripts/vote/result.js index 2c9847376..9c111ac2d 100644 --- a/examples/permissioned-voting/scripts/vote/result.js +++ b/examples/permissioned-voting/scripts/vote/result.js @@ -1,5 +1,5 @@ const { readGlobalStateSSC } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); const { executeTransaction } = require('./common'); async function run (runtimeEnv, deployer) { @@ -7,7 +7,7 @@ async function run (runtimeEnv, deployer) { const alice = deployer.accountsByName.get('alice'); // Retreive AppInfo from checkpoints. - const appInfo = deployer.getSSC('permissioned-voting-approval.py', 'permissioned-voting-clear.py'); + const appInfo = deployer.getApp('permissioned-voting-approval.py', 'permissioned-voting-clear.py'); // Retreive Global State const globalState = await readGlobalStateSSC(deployer, votingAdminAccount.addr, appInfo.appID); @@ -37,7 +37,7 @@ async function run (runtimeEnv, deployer) { } const txnParam = { - type: types.TransactionType.DeleteSSC, + type: types.TransactionType.DeleteApp, sign: types.SignType.SecretKey, fromAccount: votingAdminAccount, appID: appInfo.appID, @@ -49,7 +49,7 @@ async function run (runtimeEnv, deployer) { await executeTransaction(deployer, txnParam); txnParam.fromAccount = alice; - txnParam.type = types.TransactionType.ClearSSC; + txnParam.type = types.TransactionType.ClearApp; // Clear voter's account console.log("Clearing Alice's Account"); diff --git a/examples/permissioned-voting/scripts/vote/vote.js b/examples/permissioned-voting/scripts/vote/vote.js index 5bf7ec27c..9c107246c 100644 --- a/examples/permissioned-voting/scripts/vote/vote.js +++ b/examples/permissioned-voting/scripts/vote/vote.js @@ -1,4 +1,5 @@ -const { types, stringToBytes } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); +const { convert } = require('@algo-builder/algob'); const { executeTransaction } = require('./common'); async function run (runtimeEnv, deployer) { @@ -30,11 +31,11 @@ async function run (runtimeEnv, deployer) { // App arguments to vote for "candidatea". const appArgs = [ - stringToBytes('vote'), stringToBytes('candidatea') + convert.stringToBytes('vote'), convert.stringToBytes('candidatea') ]; // Get AppInfo and AssetID from checkpoints. - const appInfo = deployer.getSSC('permissioned-voting-approval.py', 'permissioned-voting-clear.py'); + const appInfo = deployer.getApp('permissioned-voting-approval.py', 'permissioned-voting-clear.py'); const voteAssetID = deployer.asa.get('vote-token').assetIndex; // Atomic Transaction (Stateful Smart Contract call + Asset Transfer) diff --git a/examples/permissioned-voting/scripts/voting.js b/examples/permissioned-voting/scripts/voting.js index db8fddc6a..e9fc977f3 100644 --- a/examples/permissioned-voting/scripts/voting.js +++ b/examples/permissioned-voting/scripts/voting.js @@ -1,5 +1,5 @@ const { executeTransaction, convert } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); @@ -55,7 +55,7 @@ async function run (runtimeEnv, deployer) { // Create Application // Note: An Account can have maximum of 10 Applications. - const res = await deployer.deploySSC( + const res = await deployer.deployApp( 'permissioned-voting-approval.py', 'permissioned-voting-clear.py', { sender: votingAdminAccount, @@ -73,7 +73,7 @@ async function run (runtimeEnv, deployer) { console.log('Opting-In for Alice in voting application'); try { - await deployer.optInAccountToSSC(alice, res.appID, {}, { appArgs: reg }); + await deployer.optInAccountToApp(alice, res.appID, {}, { appArgs: reg }); } catch (e) { console.log(e); throw new Error(e); diff --git a/examples/ref-templates/scripts/common/common.js b/examples/ref-templates/scripts/common/common.js index 47ca7704a..72d3ccb25 100644 --- a/examples/ref-templates/scripts/common/common.js +++ b/examples/ref-templates/scripts/common/common.js @@ -1,5 +1,5 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); exports.executeTransaction = async function (deployer, txnParams) { try { diff --git a/examples/ref-templates/scripts/htlc.js b/examples/ref-templates/scripts/htlc.js index 9e35a8e23..300789173 100644 --- a/examples/ref-templates/scripts/htlc.js +++ b/examples/ref-templates/scripts/htlc.js @@ -1,6 +1,6 @@ const { executeTransaction, mkTxnParams } = require('./common/common'); const { globalZeroAddress, convert } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); diff --git a/examples/stateful-counter/README.md b/examples/stateful-counter/README.md index d08b21335..b5ce6f319 100644 --- a/examples/stateful-counter/README.md +++ b/examples/stateful-counter/README.md @@ -99,7 +99,7 @@ Firstly we need to fund the contract. `master` account will fund it (as it has l ```javascript // Create Application // Note: An Account can have maximum of 10 Applications. -const sscInfo = await deployer.deploySSC( +const sscInfo = await deployer.deployApp( 'approval_program.teal', // approval program 'clear_program.teal', // clear program { @@ -138,7 +138,7 @@ Created new app-id: 189 To Opt-In to an application use the following code in one of your scripts (in `./scripts`): ```javascript -await deployer.optInAccountToSSC(account, applicationID, {}, {}); +await deployer.optInAccountToApp(account, applicationID, {}, {}); ``` where `Account` is the account you want to opt-in and applicationID is application index. @@ -189,7 +189,7 @@ here key 'Y291bnRlcg==' is base64 encoded form of `counter`. To update an application with (new_approval.teal, new_clear.teal), you can use: ```javascript -const updatedRes = await deployer.updateSSC( +const updatedRes = await deployer.updateApp( creatorAccount, {}, // pay flags applicationID, @@ -206,7 +206,7 @@ To delete an existing application you can use: ```javascript const tx = { - type: types.TransactionType.DeleteSSC, + type: types.TransactionType.DeleteApp, sign: types.SignType.SecretKey, fromAccount: creatorAccount, appID: applicationID, diff --git a/examples/stateful-counter/scripts/deploy.js b/examples/stateful-counter/scripts/deploy.js index 5db72899f..d5a9ce06a 100644 --- a/examples/stateful-counter/scripts/deploy.js +++ b/examples/stateful-counter/scripts/deploy.js @@ -1,7 +1,7 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const masterAccount = deployer.accountsByName.get('master-account'); @@ -20,7 +20,7 @@ async function run (runtimeEnv, deployer) { // Create Application // Note: An Account can have maximum of 10 Applications. - const sscInfo = await deployer.deploySSC( + const sscInfo = await deployer.deployApp( 'approval_program.teal', // approval program 'clear_program.teal', // clear program { @@ -34,7 +34,7 @@ async function run (runtimeEnv, deployer) { console.log(sscInfo); // Opt-In for creator - await deployer.optInAccountToSSC(creatorAccount, sscInfo.appID, {}, {}); + await deployer.optInAccountToApp(creatorAccount, sscInfo.appID, {}, {}); } module.exports = { default: run }; diff --git a/examples/stateful-counter/scripts/interaction/call_application.js b/examples/stateful-counter/scripts/interaction/call_application.js index 07bc9902b..23dc073a3 100644 --- a/examples/stateful-counter/scripts/interaction/call_application.js +++ b/examples/stateful-counter/scripts/interaction/call_application.js @@ -1,11 +1,11 @@ const { readGlobalStateSSC, executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const creatorAccount = deployer.accountsByName.get('alice'); // Retreive AppInfo from checkpoints. - const appInfo = deployer.getSSC('approval_program.teal', 'clear_program.teal'); + const appInfo = deployer.getApp('approval_program.teal', 'clear_program.teal'); const applicationID = appInfo.appID; console.log('Application Id ', applicationID); diff --git a/examples/stateful-counter/scripts/interaction/delete_application.js b/examples/stateful-counter/scripts/interaction/delete_application.js index 6c7bbcd11..4cdbabf2f 100644 --- a/examples/stateful-counter/scripts/interaction/delete_application.js +++ b/examples/stateful-counter/scripts/interaction/delete_application.js @@ -1,16 +1,16 @@ const { executeTransaction } = require('@algo-builder/algob'); -const { types } = require('@algo-builder/runtime'); +const { types } = require('@algo-builder/web'); async function run (runtimeEnv, deployer) { const creatorAccount = deployer.accountsByName.get('alice'); // Retreive AppInfo from checkpoints. - const appInfo = deployer.getSSC('approval_program.teal', 'clear_program.teal'); + const appInfo = deployer.getApp('approval_program.teal', 'clear_program.teal'); const applicationID = appInfo.appID; console.log('Application Id ', applicationID); const tx = { - type: types.TransactionType.DeleteSSC, + type: types.TransactionType.DeleteApp, sign: types.SignType.SecretKey, fromAccount: creatorAccount, appID: applicationID, diff --git a/examples/stateful-counter/scripts/interaction/update_application.js b/examples/stateful-counter/scripts/interaction/update_application.js index bcf85d114..42c888842 100644 --- a/examples/stateful-counter/scripts/interaction/update_application.js +++ b/examples/stateful-counter/scripts/interaction/update_application.js @@ -2,11 +2,11 @@ async function run (runtimeEnv, deployer) { const creatorAccount = deployer.accountsByName.get('alice'); // Retreive AppInfo from checkpoints. - const appInfo = deployer.getSSC('approval_program.teal', 'clear_program.teal'); + const appInfo = deployer.getApp('approval_program.teal', 'clear_program.teal'); const applicationID = appInfo.appID; console.log('Application Id ', applicationID); - const updatedRes = await deployer.updateSSC( + const updatedRes = await deployer.updateApp( creatorAccount, {}, // pay flags applicationID, diff --git a/package.json b/package.json index 038dcbdb3..03df9982c 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "license": "Apache-2.0", "private": true, "workspaces": [ + "packages/web", "packages/runtime", "packages/*", "examples/*" diff --git a/packages/algob/package.json b/packages/algob/package.json index 23a588355..542f2dbe4 100644 --- a/packages/algob/package.json +++ b/packages/algob/package.json @@ -63,6 +63,7 @@ "sample-project/" ], "devDependencies": { + "@algo-builder/web": "0.0.1", "@algo-builder/types-algosdk": "^1.1.0", "@types/chai": "^4.2.12", "@types/debug": "^4.1.5", diff --git a/packages/algob/src/builtin-tasks/deploy.ts b/packages/algob/src/builtin-tasks/deploy.ts index 552110c21..144d200df 100644 --- a/packages/algob/src/builtin-tasks/deploy.ts +++ b/packages/algob/src/builtin-tasks/deploy.ts @@ -1,9 +1,8 @@ +import { BuilderError, ERRORS } from "@algo-builder/web"; import fs from "fs"; import glob from "glob"; import path from "path"; -import { BuilderError } from "../errors/errors"; -import { ERRORS } from "../errors/errors-list"; import { task } from "../internal/core/config/config-env"; import { AlgoOperator, createAlgoOperator } from "../lib/algo-operator"; import { cmpStr } from "../lib/comparators"; diff --git a/packages/algob/src/builtin-tasks/gen-accounts.ts b/packages/algob/src/builtin-tasks/gen-accounts.ts index 07a8889e6..54fb750da 100644 --- a/packages/algob/src/builtin-tasks/gen-accounts.ts +++ b/packages/algob/src/builtin-tasks/gen-accounts.ts @@ -1,9 +1,9 @@ +import { BuilderError, ERRORS } from "@algo-builder/web"; import algosdk from "algosdk"; import * as _fs from "fs"; import * as path from "path"; import YAML from "yaml"; -import { BuilderError, ERRORS } from "../errors/errors"; import { task } from "../internal/core/config/config-env"; import * as types from "../internal/core/params/argument-types"; import { assertAllDirs, ASSETS_DIR } from "../internal/core/project-structure"; diff --git a/packages/algob/src/builtin-tasks/run.ts b/packages/algob/src/builtin-tasks/run.ts index 05ac393f6..caa578168 100644 --- a/packages/algob/src/builtin-tasks/run.ts +++ b/packages/algob/src/builtin-tasks/run.ts @@ -1,8 +1,7 @@ +import { BuilderError, ERRORS } from "@algo-builder/web"; import debug from "debug"; import fsExtra from "fs-extra"; -import { BuilderError } from "../errors/errors"; -import { ERRORS } from "../errors/errors-list"; import { task } from "../internal/core/config/config-env"; import { DeployerConfig, mkDeployer } from "../internal/deployer_cfg"; import { TxWriterImpl } from "../internal/tx-log-writer"; diff --git a/packages/algob/src/index.ts b/packages/algob/src/index.ts index be8a461a5..197bad2e0 100644 --- a/packages/algob/src/index.ts +++ b/packages/algob/src/index.ts @@ -1,6 +1,5 @@ -import { addressToPk, stringToBytes, uint64ToBigEndian } from "@algo-builder/runtime"; +import { ERRORS, parsing as convert } from "@algo-builder/web"; -import * as ERRORS from "./errors/errors-list"; import { createMsigAddress, loadAccountsFromEnv, @@ -17,7 +16,6 @@ import { balanceOf, printAssets, printGlobalStateSSC, printLocalStateSSC, readGl import { executeSignedTxnFromFile, executeTransaction, getSuggestedParams, mkTxParams } from "./lib/tx"; import * as runtime from "./runtime"; import * as types from "./types"; -const convert = { uint64ToBigEndian, addressToPk, stringToBytes }; export { ERRORS, mkAccounts, diff --git a/packages/algob/src/internal/cli/arguments-parser.ts b/packages/algob/src/internal/cli/arguments-parser.ts index 2cded011e..ea2c6f2d4 100644 --- a/packages/algob/src/internal/cli/arguments-parser.ts +++ b/packages/algob/src/internal/cli/arguments-parser.ts @@ -1,5 +1,5 @@ -import { BuilderError } from "../../errors/errors"; -import { ERRORS } from "../../errors/errors-list"; +import { BuilderError, ERRORS } from "@algo-builder/web"; + import { ParamDefinition, ParamDefinitions, diff --git a/packages/algob/src/internal/cli/cli.ts b/packages/algob/src/internal/cli/cli.ts index 74a3b6bcc..fc8feec26 100644 --- a/packages/algob/src/internal/cli/cli.ts +++ b/packages/algob/src/internal/cli/cli.ts @@ -2,13 +2,12 @@ // -*- mode: typescript -*- // https://github.com/syl20bnr/spacemacs/issues/13715 import "source-map-support/register"; +import { BuilderError, BuilderPluginError, ERRORS } from "@algo-builder/web"; import chalk from "chalk"; import debug from "debug"; import semver from "semver"; -import { TASK_HELP, TASK_INIT } from "../../builtin-tasks/task-names"; -import { BuilderError, BuilderPluginError } from "../../errors/errors"; -import { ERRORS } from "../../errors/errors-list"; +import { TASK_HELP } from "../../builtin-tasks/task-names"; import { checkAlgorandUnauthorized } from "../../lib/exceptions"; import { RuntimeArgs, RuntimeEnv, TaskArguments } from "../../types"; import { ALGOB_NAME } from "../constants"; @@ -225,10 +224,10 @@ async function main (): Promise { log(`Quitting algob after successfully running task ${taskName}`); } catch (error) { if (BuilderError.isBuilderError(error)) { - console.error(chalk.red(`Error ${error.message}`)); + console.error(chalk.red(`Error ${error.message}`)); // eslint-disable-line @typescript-eslint/restrict-template-expressions } else if (BuilderPluginError.isBuilderPluginError(error)) { console.error( - chalk.red(`Error in plugin ${error.pluginName ?? ""}: ${error.message}`) + chalk.red(`Error in plugin ${error.pluginName ?? ""}: ${error.message}`) // eslint-disable-line @typescript-eslint/restrict-template-expressions ); } else if (error instanceof Error) { console.error(chalk.red("An unexpected error occurred:"), error.message); diff --git a/packages/algob/src/internal/cli/help-printer.ts b/packages/algob/src/internal/cli/help-printer.ts index cac1508e7..13267b1f0 100644 --- a/packages/algob/src/internal/cli/help-printer.ts +++ b/packages/algob/src/internal/cli/help-printer.ts @@ -1,5 +1,5 @@ -import { BuilderError } from "../../errors/errors"; -import { ERRORS } from "../../errors/errors-list"; +import { BuilderError, ERRORS } from "@algo-builder/web"; + import { cmpStr } from "../../lib/comparators"; import { ParamDefinition, diff --git a/packages/algob/src/internal/cli/project-creation.ts b/packages/algob/src/internal/cli/project-creation.ts index a7b8a24d1..e161cb446 100644 --- a/packages/algob/src/internal/cli/project-creation.ts +++ b/packages/algob/src/internal/cli/project-creation.ts @@ -1,10 +1,9 @@ +import { BuilderError, ERRORS } from "@algo-builder/web"; import chalk from "chalk"; import fsExtra from "fs-extra"; import os from "os"; import path from "path"; -import { BuilderError } from "../../errors/errors"; -import { ERRORS } from "../../errors/errors-list"; import type { PromiseAny } from "../../types"; import { ALGOB_NAME } from "../constants"; import { ExecutionMode, getExecutionMode } from "../core/execution-mode"; diff --git a/packages/algob/src/internal/context.ts b/packages/algob/src/internal/context.ts index 326e831d2..7c27731d5 100644 --- a/packages/algob/src/internal/context.ts +++ b/packages/algob/src/internal/context.ts @@ -1,5 +1,5 @@ -import { BuilderError } from "../errors/errors"; -import { ERRORS } from "../errors/errors-list"; +import { BuilderError, ERRORS } from "@algo-builder/web"; + import { ConfigExtender, RuntimeEnv } from "../types"; import { ExtenderManager } from "./core/config/extenders"; import { TasksDSL } from "./core/tasks/dsl"; diff --git a/packages/algob/src/internal/core/config/config-validation.ts b/packages/algob/src/internal/core/config/config-validation.ts index c10a71b60..a20973e94 100644 --- a/packages/algob/src/internal/core/config/config-validation.ts +++ b/packages/algob/src/internal/core/config/config-validation.ts @@ -1,8 +1,7 @@ import { parseZodError } from "@algo-builder/runtime"; +import { BuilderError, ERRORS } from "@algo-builder/web"; import * as z from 'zod'; -import { BuilderError } from "../../../errors/errors"; -import { ERRORS } from "../../../errors/errors-list"; import { validateAccount } from "../../../lib/account"; // import { Account } from "algosdk"; import type { ChainCfg, HttpNetworkConfig, NetworkConfig } from "../../../types"; diff --git a/packages/algob/src/internal/core/params/argument-types.ts b/packages/algob/src/internal/core/params/argument-types.ts index f6898b76f..75075f3e4 100644 --- a/packages/algob/src/internal/core/params/argument-types.ts +++ b/packages/algob/src/internal/core/params/argument-types.ts @@ -1,8 +1,6 @@ +import { BuilderError, ERRORS } from "@algo-builder/web"; import * as fs from "fs"; -import { BuilderError } from "../../../errors/errors"; -import { ERRORS } from "../../../errors/errors-list"; - /** * Provides an interface for every valid task argument type. */ diff --git a/packages/algob/src/internal/core/params/env-variables.ts b/packages/algob/src/internal/core/params/env-variables.ts index b9f037245..cd7e16445 100644 --- a/packages/algob/src/internal/core/params/env-variables.ts +++ b/packages/algob/src/internal/core/params/env-variables.ts @@ -1,5 +1,5 @@ -import { BuilderError } from "../../../errors/errors"; -import { ERRORS } from "../../../errors/errors-list"; +import { BuilderError, ERRORS } from "@algo-builder/web"; + import { ParamDefinitions, RuntimeArgs } from "../../../types"; import { ArgumentsParser } from "../../cli/arguments-parser"; import { unsafeObjectKeys } from "../../util/unsafe"; diff --git a/packages/algob/src/internal/core/plugins.ts b/packages/algob/src/internal/core/plugins.ts index 90f927821..260bec274 100644 --- a/packages/algob/src/internal/core/plugins.ts +++ b/packages/algob/src/internal/core/plugins.ts @@ -1,9 +1,8 @@ +import { BuilderError, ERRORS } from "@algo-builder/web"; import debug from "debug"; import * as path from "path"; import * as semver from "semver"; -import { BuilderError } from "../../errors/errors"; -import { ERRORS } from "../../errors/errors-list"; import { StrMap } from "../../types"; import { BuilderContext } from "../context"; import { ExecutionMode, getExecutionMode } from "./execution-mode"; diff --git a/packages/algob/src/internal/core/runtime-environment.ts b/packages/algob/src/internal/core/runtime-environment.ts index a5100e2d0..1955b890c 100644 --- a/packages/algob/src/internal/core/runtime-environment.ts +++ b/packages/algob/src/internal/core/runtime-environment.ts @@ -1,7 +1,6 @@ +import { BuilderError, ERRORS } from "@algo-builder/web"; import debug from "debug"; -import { BuilderError } from "../../errors/errors"; -import { ERRORS } from "../../errors/errors-list"; import type { EnvironmentExtender, Network, diff --git a/packages/algob/src/internal/core/tasks/task-definitions.ts b/packages/algob/src/internal/core/tasks/task-definitions.ts index dc54bdbac..610b0c603 100644 --- a/packages/algob/src/internal/core/tasks/task-definitions.ts +++ b/packages/algob/src/internal/core/tasks/task-definitions.ts @@ -1,5 +1,5 @@ -import { BuilderError } from "../../../errors/errors"; -import { ErrorDescriptor, ERRORS } from "../../../errors/errors-list"; +import { BuilderError, ErrorDescriptor, ERRORS } from "@algo-builder/web"; + import { ActionType, ParamDefinitionAny, diff --git a/packages/algob/src/internal/deployer.ts b/packages/algob/src/internal/deployer.ts index 2394d579c..03d54f5f6 100644 --- a/packages/algob/src/internal/deployer.ts +++ b/packages/algob/src/internal/deployer.ts @@ -1,9 +1,8 @@ import { overrideASADef, types as rtypes } from "@algo-builder/runtime"; +import { BuilderError, ERRORS, types as wtypes } from "@algo-builder/web"; import type { LogicSig, MultiSig } from "algosdk"; import * as algosdk from "algosdk"; -import { BuilderError } from "../errors/errors"; -import { ERRORS } from "../errors/errors-list"; import { txWriter } from "../internal/tx-log-writer"; import { AlgoOperator } from "../lib/algo-operator"; import { getDummyLsig, getLsig } from "../lib/lsig"; @@ -25,7 +24,7 @@ import { DeployerConfig } from "./deployer_cfg"; class DeployerBasicMode { protected readonly runtimeEnv: RuntimeEnv; protected readonly cpData: CheckpointRepo; - protected readonly loadedAsaDefs: rtypes.ASADefs; + protected readonly loadedAsaDefs: wtypes.ASADefs; protected readonly algoOp: AlgoOperator; protected readonly txWriter: txWriter; readonly accounts: rtypes.Account[]; @@ -78,7 +77,7 @@ class DeployerBasicMode { * @param name Asset name * @param asaParams Asa parameters if user wants to override existing asa definition */ - getASADef (name: string, asaParams?: Partial): rtypes.ASADef { + getASADef (name: string, asaParams?: Partial): wtypes.ASADef { return overrideASADef(this.accountsByName, this.loadedAsaDefs[name], asaParams); } @@ -125,7 +124,7 @@ class DeployerBasicMode { * of asaDef could be updated during tx execution (eg. update asset clawback) * @param asaName asset name in asa.yaml */ - loadASADef (asaName: string): rtypes.ASADef | undefined { + loadASADef (asaName: string): wtypes.ASADef | undefined { const asaMap = this.cpData.precedingCP[this.networkName]?.asa ?? new Map(); return asaMap.get(asaName)?.assetDef; } @@ -135,8 +134,8 @@ class DeployerBasicMode { * @param nameApproval Approval program name * @param nameClear clear program name */ - getSSC (nameApproval: string, nameClear: string): rtypes.SSCInfo | undefined { - return this.checkpoint.getSSCfromCPKey(nameApproval + "-" + nameClear); + getApp (nameApproval: string, nameClear: string): rtypes.SSCInfo | undefined { + return this.checkpoint.getAppfromCPKey(nameApproval + "-" + nameClear); } /** @@ -193,8 +192,8 @@ class DeployerBasicMode { */ async optInAcountToASA (asa: string, accountName: string, flags: rtypes.TxParams): Promise { this.assertCPNotDeleted({ - type: rtypes.TransactionType.OptInASA, - sign: rtypes.SignType.SecretKey, + type: wtypes.TransactionType.OptInASA, + sign: wtypes.SignType.SecretKey, fromAccount: this._getAccount(accountName), assetID: asa, payFlags: {} @@ -229,8 +228,8 @@ class DeployerBasicMode { */ async optInLsigToASA (asa: string, lsig: LogicSig, flags: rtypes.TxParams): Promise { this.assertCPNotDeleted({ - type: rtypes.TransactionType.OptInASA, - sign: rtypes.SignType.LogicSignature, + type: wtypes.TransactionType.OptInASA, + sign: wtypes.SignType.LogicSignature, fromAccountAddr: lsig.address(), lsig: lsig, assetID: asa, @@ -257,19 +256,19 @@ class DeployerBasicMode { * @param payFlags Transaction flags * @param flags Optional parameters to SSC (accounts, args..) */ - async optInAccountToSSC ( + async optInAccountToApp ( sender: rtypes.Account, appID: number, payFlags: rtypes.TxParams, - flags: rtypes.SSCOptionalFlags): Promise { + flags: rtypes.AppOptionalFlags): Promise { this.assertCPNotDeleted({ - type: rtypes.TransactionType.OptInSSC, - sign: rtypes.SignType.SecretKey, + type: wtypes.TransactionType.OptInToApp, + sign: wtypes.SignType.SecretKey, fromAccount: sender, appID: appID, payFlags: {} }); - await this.algoOp.optInAccountToSSC(sender, appID, payFlags, flags); + await this.algoOp.optInAccountToApp(sender, appID, payFlags, flags); } /** @@ -280,20 +279,20 @@ class DeployerBasicMode { * @param payFlags Transaction flags * @param flags Optional parameters to SSC (accounts, args..) */ - async optInLsigToSSC ( + async optInLsigToApp ( appID: number, lsig: LogicSig, payFlags: rtypes.TxParams, - flags: rtypes.SSCOptionalFlags): Promise { + flags: rtypes.AppOptionalFlags): Promise { this.assertCPNotDeleted({ - type: rtypes.TransactionType.OptInSSC, - sign: rtypes.SignType.LogicSignature, + type: wtypes.TransactionType.OptInToApp, + sign: wtypes.SignType.LogicSignature, fromAccountAddr: lsig.address(), lsig: lsig, appID: appID, payFlags: {} }); - await this.algoOp.optInLsigToSSC(appID, lsig, payFlags, flags); + await this.algoOp.optInLsigToApp(appID, lsig, payFlags, flags); } /** @@ -343,7 +342,7 @@ class DeployerBasicMode { */ private assertAppExist (appID: number): void { const key = this.checkpoint.getAppCheckpointKeyFromIndex(appID); - const res = key ? this.checkpoint.getSSCfromCPKey(key) : undefined; + const res = key ? this.checkpoint.getAppfromCPKey(key) : undefined; if (res?.deleted === true) { throw new BuilderError( ERRORS.GENERAL.APP_DELETED, { @@ -356,30 +355,30 @@ class DeployerBasicMode { * Group transactions into asa and app, check for cp deletion * @param txn Transaction execution parameter */ - private _assertCpNotDeleted (txn: rtypes.ExecParams): void { + private _assertCpNotDeleted (txn: wtypes.ExecParams): void { switch (txn.type) { - case rtypes.TransactionType.ModifyAsset: - case rtypes.TransactionType.FreezeAsset: - case rtypes.TransactionType.RevokeAsset: - case rtypes.TransactionType.OptInASA: - case rtypes.TransactionType.DestroyAsset: { + case wtypes.TransactionType.ModifyAsset: + case wtypes.TransactionType.FreezeAsset: + case wtypes.TransactionType.RevokeAsset: + case wtypes.TransactionType.OptInASA: + case wtypes.TransactionType.DestroyAsset: { this.assertASAExist(txn.assetID); break; } // https://developer.algorand.org/articles/algos-asas/#opting-in-and-out-of-asas // https://developer.algorand.org/docs/reference/transactions/#asset-transfer-transaction - case rtypes.TransactionType.TransferAsset: { + case wtypes.TransactionType.TransferAsset: { // If transaction is not opt-out check for CP deletion if (txn.payFlags.closeRemainderTo === undefined) { this.assertASAExist(txn.assetID); } break; } - case rtypes.TransactionType.DeleteSSC: - case rtypes.TransactionType.CloseSSC: - case rtypes.TransactionType.OptInSSC: - case rtypes.TransactionType.UpdateSSC: - case rtypes.TransactionType.CallNoOpSSC: { + case wtypes.TransactionType.DeleteApp: + case wtypes.TransactionType.CloseApp: + case wtypes.TransactionType.OptInToApp: + case wtypes.TransactionType.UpdateApp: + case wtypes.TransactionType.CallNoOpSSC: { this.assertAppExist(txn.appID); break; } @@ -392,7 +391,7 @@ class DeployerBasicMode { * throw error(except for opt-out transactions), else pass * @param execParams Transaction execution parameters */ - assertCPNotDeleted (execParams: rtypes.ExecParams | rtypes.ExecParams[]): void { + assertCPNotDeleted (execParams: wtypes.ExecParams | wtypes.ExecParams[]): void { if (Array.isArray(execParams)) { for (const txn of execParams) { this._assertCpNotDeleted(txn); @@ -470,7 +469,7 @@ export class DeployerDeployMode extends DeployerBasicMode implements Deployer { async deployASA ( name: string, flags: rtypes.ASADeploymentFlags, - asaParams?: Partial + asaParams?: Partial ): Promise { const asaDef = overrideASADef(this.accountsByName, this.loadedAsaDefs[name], asaParams); @@ -566,22 +565,22 @@ export class DeployerDeployMode extends DeployerBasicMode implements Deployer { * Deploys Algorand Stateful Smart Contract * @param approvalProgram filename which has approval program * @param clearProgram filename which has clear program - * @param flags SSCDeploymentFlags + * @param flags AppDeploymentFlags * @param payFlags Transaction Params * @param scTmplParams: scTmplParams: Smart contract template parameters * (used only when compiling PyTEAL to TEAL) */ - async deploySSC ( + async deployApp ( approvalProgram: string, clearProgram: string, - flags: rtypes.SSCDeploymentFlags, + flags: rtypes.AppDeploymentFlags, payFlags: rtypes.TxParams, scTmplParams?: SCParams): Promise { const name = approvalProgram + "-" + clearProgram; this.assertNoAsset(name); let sscInfo = {} as rtypes.SSCInfo; try { - sscInfo = await this.algoOp.deploySSC( + sscInfo = await this.algoOp.deployApp( approvalProgram, clearProgram, flags, payFlags, this.txWriter, scTmplParams); } catch (error) { this.persistCP(); @@ -604,17 +603,17 @@ export class DeployerDeployMode extends DeployerBasicMode implements Deployer { * @param newClearProgram New Clear Program filename * @param flags Optional parameters to SSC (accounts, args..) */ - async updateSSC ( + async updateApp ( sender: algosdk.Account, payFlags: rtypes.TxParams, appID: number, newApprovalProgram: string, newClearProgram: string, - flags: rtypes.SSCOptionalFlags + flags: rtypes.AppOptionalFlags ): Promise { this.assertCPNotDeleted({ - type: rtypes.TransactionType.UpdateSSC, - sign: rtypes.SignType.SecretKey, + type: wtypes.TransactionType.UpdateApp, + sign: wtypes.SignType.SecretKey, fromAccount: sender, newApprovalProgram: newApprovalProgram, newClearProgram: newClearProgram, @@ -625,7 +624,7 @@ export class DeployerDeployMode extends DeployerBasicMode implements Deployer { let sscInfo = {} as rtypes.SSCInfo; try { - sscInfo = await this.algoOp.updateSSC(sender, payFlags, appID, + sscInfo = await this.algoOp.updateApp(sender, payFlags, appID, newApprovalProgram, newClearProgram, flags, this.txWriter); } catch (error) { this.persistCP(); @@ -706,20 +705,20 @@ export class DeployerRunMode extends DeployerBasicMode implements Deployer { }); } - async deploySSC ( + async deployApp ( approvalProgram: string, clearProgram: string, - flags: rtypes.SSCDeploymentFlags, + flags: rtypes.AppDeploymentFlags, payFlags: rtypes.TxParams, scInitParam?: unknown): Promise { throw new BuilderError(ERRORS.BUILTIN_TASKS.DEPLOYER_EDIT_OUTSIDE_DEPLOY, { - methodName: "deploySSC" + methodName: "deployApp" }); } /** * This functions updates SSC in the network. - * Note: UpdateSSC when ran in RunMode it doesn't store checkpoints + * Note: updateApp when ran in RunMode it doesn't store checkpoints * @param sender Sender account * @param payFlags transaction parameters * @param appID application index @@ -727,24 +726,24 @@ export class DeployerRunMode extends DeployerBasicMode implements Deployer { * @param newClearProgram new clear program name * @param flags SSC optional flags */ - async updateSSC ( + async updateApp ( sender: algosdk.Account, payFlags: rtypes.TxParams, appID: number, newApprovalProgram: string, newClearProgram: string, - flags: rtypes.SSCOptionalFlags + flags: rtypes.AppOptionalFlags ): Promise { this.assertCPNotDeleted({ - type: rtypes.TransactionType.UpdateSSC, - sign: rtypes.SignType.SecretKey, + type: wtypes.TransactionType.UpdateApp, + sign: wtypes.SignType.SecretKey, fromAccount: sender, newApprovalProgram: newApprovalProgram, newClearProgram: newClearProgram, appID: appID, payFlags: {} }); - return await this.algoOp.updateSSC( + return await this.algoOp.updateApp( sender, payFlags, appID, newApprovalProgram, newClearProgram, flags, this.txWriter diff --git a/packages/algob/src/internal/deployer_cfg.ts b/packages/algob/src/internal/deployer_cfg.ts index deddbd7a6..8c8e55580 100644 --- a/packages/algob/src/internal/deployer_cfg.ts +++ b/packages/algob/src/internal/deployer_cfg.ts @@ -1,4 +1,5 @@ import { loadASAFile, types as rtypes } from "@algo-builder/runtime"; +import { types as wtypes } from "@algo-builder/web"; import { mkAccountIndex } from "../lib/account"; import { AlgoOperator } from "../lib/algo-operator"; @@ -25,7 +26,7 @@ export function mkDeployer ( export class DeployerConfig { runtimeEnv: RuntimeEnv; cpData: CheckpointRepo; - asaDefs: rtypes.ASADefs; + asaDefs: wtypes.ASADefs; algoOp: AlgoOperator; txWriter: txWriter; accounts: rtypes.AccountMap; diff --git a/packages/algob/src/internal/util/lazy.ts b/packages/algob/src/internal/util/lazy.ts index 3be87d01e..a2607f951 100644 --- a/packages/algob/src/internal/util/lazy.ts +++ b/packages/algob/src/internal/util/lazy.ts @@ -1,8 +1,6 @@ +import { BuilderError, ERRORS } from "@algo-builder/web"; import * as util from "util"; -import { BuilderError } from "../../errors/errors"; -import { ERRORS } from "../../errors/errors-list"; - /** * This module provides function to implement proxy-based object, functions, and * classes (they are functions). They receive an initializer function that it's diff --git a/packages/algob/src/internal/util/scripts-runner.ts b/packages/algob/src/internal/util/scripts-runner.ts index 606c6e267..c78a7a818 100644 --- a/packages/algob/src/internal/util/scripts-runner.ts +++ b/packages/algob/src/internal/util/scripts-runner.ts @@ -1,7 +1,7 @@ +import { BuilderError, ERRORS, parseAlgorandError } from "@algo-builder/web"; import debug from "debug"; import * as path from "path"; -import { BuilderError, ERRORS, parseAlgorandError } from "../../errors/errors"; import { Deployer, RuntimeEnv } from "../../types"; const log = debug("algob:core:scripts-runner"); diff --git a/packages/algob/src/lib/account.ts b/packages/algob/src/lib/account.ts index ddf6e870c..eae81b134 100644 --- a/packages/algob/src/lib/account.ts +++ b/packages/algob/src/lib/account.ts @@ -1,10 +1,9 @@ import { types as rtypes } from "@algo-builder/runtime"; +import { BuilderError, ERRORS } from "@algo-builder/web"; import { Account as AccountSDK, Kmd, mnemonicToSecretKey, multisigAddress, MultisigMetadata } from "algosdk"; import * as fs from "fs"; import YAML from "yaml"; -import { BuilderError } from "../errors/errors"; -import { ERRORS } from "../errors/errors-list"; import CfgErrors, { ErrorPutter } from "../internal/core/config/config-errors"; import type { Account, AccountDef, HDAccount, KmdCfg, KmdWallet, MnemonicAccount, StrMap } from "../types"; diff --git a/packages/algob/src/lib/algo-operator.ts b/packages/algob/src/lib/algo-operator.ts index ceb3efa10..a97b90ca3 100644 --- a/packages/algob/src/lib/algo-operator.ts +++ b/packages/algob/src/lib/algo-operator.ts @@ -1,8 +1,7 @@ -import { encodeNote, mkTransaction, types as rtypes } from "@algo-builder/runtime"; +import { types as rtypes } from "@algo-builder/runtime"; +import { BuilderError, ERRORS, tx as webTx, types as wtypes } from "@algo-builder/web"; import algosdk, { LogicSig } from "algosdk"; -import { BuilderError } from "../errors/errors"; -import { ERRORS } from "../errors/errors-list"; import { txWriter } from "../internal/tx-log-writer"; import { createClient } from "../lib/driver"; import { getLsig } from "../lib/lsig"; @@ -29,25 +28,25 @@ export function createAlgoOperator (network: Network): AlgoOperator { export interface AlgoOperator { algodClient: algosdk.Algodv2 deployASA: ( - name: string, asaDef: rtypes.ASADef, + name: string, asaDef: wtypes.ASADef, flags: rtypes.ASADeploymentFlags, accounts: rtypes.AccountMap, txWriter: txWriter ) => Promise fundLsig: (name: string, flags: FundASCFlags, payFlags: rtypes.TxParams, txWriter: txWriter, scTmplParams?: SCParams) => Promise - deploySSC: ( + deployApp: ( approvalProgram: string, clearProgram: string, - flags: rtypes.SSCDeploymentFlags, + flags: rtypes.AppDeploymentFlags, payFlags: rtypes.TxParams, txWriter: txWriter, scTmplParams?: SCParams) => Promise - updateSSC: ( + updateApp: ( sender: algosdk.Account, payFlags: rtypes.TxParams, appID: number, newApprovalProgram: string, newClearProgram: string, - flags: rtypes.SSCOptionalFlags, + flags: rtypes.AppOptionalFlags, txWriter: txWriter ) => Promise waitForConfirmation: (txId: string) => Promise @@ -59,15 +58,15 @@ export interface AlgoOperator { asaName: string, assetIndex: number, lsig: algosdk.LogicSig, params: rtypes.TxParams ) => Promise optInToASAMultiple: ( - asaName: string, asaDef: rtypes.ASADef, + asaName: string, asaDef: wtypes.ASADef, flags: rtypes.ASADeploymentFlags, accounts: rtypes.AccountMap, assetIndex: number ) => Promise - optInAccountToSSC: ( + optInAccountToApp: ( sender: rtypes.Account, appID: number, - payFlags: rtypes.TxParams, flags: rtypes.SSCOptionalFlags) => Promise - optInLsigToSSC: ( + payFlags: rtypes.TxParams, flags: rtypes.AppOptionalFlags) => Promise + optInLsigToApp: ( appID: number, lsig: LogicSig, - payFlags: rtypes.TxParams, flags: rtypes.SSCOptionalFlags) => Promise + payFlags: rtypes.TxParams, flags: rtypes.AppOptionalFlags) => Promise ensureCompiled: (name: string, force?: boolean, scTmplParams?: SCParams) => Promise sendAndWait: (rawTxns: Uint8Array | Uint8Array[]) => Promise } @@ -171,7 +170,7 @@ export class AlgoOperatorImpl implements AlgoOperator { } async optInToASAMultiple ( - asaName: string, asaDef: rtypes.ASADef, + asaName: string, asaDef: wtypes.ASADef, flags: rtypes.ASADeploymentFlags, accounts: rtypes.AccountMap, assetIndex: number ): Promise { const txParams = await tx.mkTxParams(this.algodClient, flags); @@ -189,7 +188,7 @@ export class AlgoOperatorImpl implements AlgoOperator { async checkBalanceForOptInTx ( name: string, params: algosdk.SuggestedParams, - asaDef: rtypes.ASADef, accounts: rtypes.AccountMap, + asaDef: wtypes.ASADef, accounts: rtypes.AccountMap, creator: rtypes.Account, flags: rtypes.TxParams ): Promise { if (!asaDef.optInAccNames || asaDef.optInAccNames.length === 0) { @@ -226,7 +225,7 @@ export class AlgoOperatorImpl implements AlgoOperator { } async deployASA ( - name: string, asaDef: rtypes.ASADef, + name: string, asaDef: wtypes.ASADef, flags: rtypes.ASADeploymentFlags, accounts: rtypes.AccountMap, txWriter: txWriter): Promise { const message = 'Deploying ASA: ' + name; @@ -271,7 +270,7 @@ export class AlgoOperatorImpl implements AlgoOperator { console.log(message); const closeToRemainder = undefined; - const note = encodeNote(payFlags.note, payFlags.noteb64); + const note = webTx.encodeNote(payFlags.note, payFlags.noteb64); const t = algosdk.makePaymentTxnWithSuggestedParams(flags.funder.addr, contractAddress, flags.fundingMicroAlgo, closeToRemainder, note, @@ -292,15 +291,15 @@ export class AlgoOperatorImpl implements AlgoOperator { * Function to deploy Stateful Smart Contract * @param approvalProgram name of file in which approval program is stored * @param clearProgram name of file in which clear program is stored - * @param flags SSCDeploymentFlags + * @param flags AppDeploymentFlags * @param payFlags TxParams * @param txWriter * @param scTmplParams: Smart contract template parameters (used only when compiling PyTEAL to TEAL) */ - async deploySSC ( + async deployApp ( approvalProgram: string, clearProgram: string, - flags: rtypes.SSCDeploymentFlags, + flags: rtypes.AppDeploymentFlags, payFlags: rtypes.TxParams, txWriter: txWriter, scTmplParams?: SCParams): Promise { @@ -311,9 +310,9 @@ export class AlgoOperatorImpl implements AlgoOperator { const clear = await this.ensureCompiled(clearProgram, false, scTmplParams); const clearProg = new Uint8Array(Buffer.from(clear.compiled, "base64")); - const execParam: rtypes.ExecParams = { - type: rtypes.TransactionType.DeploySSC, - sign: rtypes.SignType.SecretKey, + const execParam: wtypes.ExecParams = { + type: wtypes.TransactionType.DeployApp, + sign: wtypes.SignType.SecretKey, fromAccount: flags.sender, approvalProgram: approvalProgram, clearProgram: clearProgram, @@ -332,7 +331,7 @@ export class AlgoOperatorImpl implements AlgoOperator { lease: flags.lease }; - const txn = mkTransaction(execParam, params); + const txn = webTx.mkTransaction(execParam, params); const txId = txn.txID().toString(); const signedTxn = txn.signTxn(flags.sender.sk); @@ -364,13 +363,13 @@ export class AlgoOperatorImpl implements AlgoOperator { * @param newClearProgram New Clear Program filename * @param flags Optional parameters to SSC (accounts, args..) */ - async updateSSC ( + async updateApp ( sender: algosdk.Account, payFlags: rtypes.TxParams, appID: number, newApprovalProgram: string, newClearProgram: string, - flags: rtypes.SSCOptionalFlags, + flags: rtypes.AppOptionalFlags, txWriter: txWriter ): Promise { const params = await tx.mkTxParams(this.algodClient, payFlags); @@ -380,9 +379,9 @@ export class AlgoOperatorImpl implements AlgoOperator { const clear = await this.ensureCompiled(newClearProgram, false); const clearProg = new Uint8Array(Buffer.from(clear.compiled, "base64")); - const execParam: rtypes.ExecParams = { - type: rtypes.TransactionType.UpdateSSC, - sign: rtypes.SignType.SecretKey, + const execParam: wtypes.ExecParams = { + type: wtypes.TransactionType.UpdateApp, + sign: wtypes.SignType.SecretKey, fromAccount: sender, appID: appID, newApprovalProgram: newApprovalProgram, @@ -398,7 +397,7 @@ export class AlgoOperatorImpl implements AlgoOperator { lease: flags.lease }; - const txn = mkTransaction(execParam, params); + const txn = webTx.mkTransaction(execParam, params); const txId = txn.txID().toString(); const signedTxn = txn.signTxn(sender.sk); @@ -428,15 +427,15 @@ export class AlgoOperatorImpl implements AlgoOperator { * @param payFlags: Transaction Params * @param flags Optional parameters to SSC (accounts, args..) */ - async optInAccountToSSC ( + async optInAccountToApp ( sender: rtypes.Account, appID: number, payFlags: rtypes.TxParams, - flags: rtypes.SSCOptionalFlags): Promise { + flags: rtypes.AppOptionalFlags): Promise { const params = await tx.mkTxParams(this.algodClient, payFlags); - const execParam: rtypes.ExecParams = { - type: rtypes.TransactionType.OptInSSC, - sign: rtypes.SignType.SecretKey, + const execParam: wtypes.ExecParams = { + type: wtypes.TransactionType.OptInToApp, + sign: wtypes.SignType.SecretKey, fromAccount: sender, appID: appID, payFlags: payFlags, @@ -446,7 +445,7 @@ export class AlgoOperatorImpl implements AlgoOperator { foreignAssets: flags.foreignAssets }; - const txn = mkTransaction(execParam, params); + const txn = webTx.mkTransaction(execParam, params); const signedTxn = txn.signTxn(sender.sk); await this.sendAndWait(signedTxn); } @@ -459,16 +458,16 @@ export class AlgoOperatorImpl implements AlgoOperator { * @param payFlags Transaction flags * @param flags Optional parameters to SSC (accounts, args..) */ - async optInLsigToSSC ( + async optInLsigToApp ( appID: number, lsig: LogicSig, payFlags: rtypes.TxParams, - flags: rtypes.SSCOptionalFlags + flags: rtypes.AppOptionalFlags ): Promise { console.log(`Contract ${lsig.address()} opt-in for SSC ID ${appID}`); const params = await tx.mkTxParams(this.algodClient, payFlags); - const execParam: rtypes.ExecParams = { - type: rtypes.TransactionType.OptInSSC, - sign: rtypes.SignType.LogicSignature, + const execParam: wtypes.ExecParams = { + type: wtypes.TransactionType.OptInToApp, + sign: wtypes.SignType.LogicSignature, fromAccountAddr: lsig.address(), lsig: lsig, appID: appID, @@ -478,9 +477,9 @@ export class AlgoOperatorImpl implements AlgoOperator { foreignApps: flags.foreignApps, foreignAssets: flags.foreignAssets }; - const optInLsigToSSCTx = mkTransaction(execParam, params); + const optInLsigToAppTx = webTx.mkTransaction(execParam, params); - const rawLsigSignedTx = algosdk.signLogicSigTransactionObject(optInLsigToSSCTx, lsig).blob; + const rawLsigSignedTx = algosdk.signLogicSigTransactionObject(optInLsigToAppTx, lsig).blob; await this.sendAndWait(rawLsigSignedTx); } diff --git a/packages/algob/src/lib/compile.ts b/packages/algob/src/lib/compile.ts index 974a74282..e31a433ef 100644 --- a/packages/algob/src/lib/compile.ts +++ b/packages/algob/src/lib/compile.ts @@ -1,4 +1,5 @@ import { getPathFromDirRecursive } from "@algo-builder/runtime"; +import { BuilderError, ERRORS, parseAlgorandError } from "@algo-builder/web"; import type { Algodv2, CompileOut } from "algosdk"; import { spawnSync, SpawnSyncReturns } from "child_process"; import * as fs from 'fs'; @@ -6,8 +7,6 @@ import * as murmurhash from 'murmurhash'; import * as path from 'path'; import YAML from "yaml"; -import { BuilderError, parseAlgorandError } from "../errors/errors"; -import { ERRORS } from "../errors/errors-list"; import { assertDir, ASSETS_DIR, CACHE_DIR } from "../internal/core/project-structure"; import { timestampNow } from "../lib/time"; import type { ASCCache, PyASCCache, ReplaceParams, SCParams } from "../types"; diff --git a/packages/algob/src/lib/files.ts b/packages/algob/src/lib/files.ts index 7c694e3f4..1f6de5311 100644 --- a/packages/algob/src/lib/files.ts +++ b/packages/algob/src/lib/files.ts @@ -1,9 +1,8 @@ import { getPathFromDirRecursive } from "@algo-builder/runtime"; +import { BuilderError, ERRORS } from "@algo-builder/web"; import fs from "fs-extra"; import path from "path"; -import { BuilderError } from "../errors/errors"; -import { ERRORS } from "../errors/errors-list"; import { ASSETS_DIR } from "../internal/core/project-structure"; function normalizePaths (mainPath: string, paths: string[]): string[] { diff --git a/packages/algob/src/lib/script-checkpoints.ts b/packages/algob/src/lib/script-checkpoints.ts index 8361339e6..d4a6b7657 100644 --- a/packages/algob/src/lib/script-checkpoints.ts +++ b/packages/algob/src/lib/script-checkpoints.ts @@ -1,13 +1,12 @@ import { checkIfAssetDeletionTx, loadFromYamlFileSilent, lsTreeWalk, types as rtypes } from "@algo-builder/runtime"; +import { BuilderError, ERRORS, types as wtypes } from "@algo-builder/web"; import { encodeAddress, Transaction } from "algosdk"; import deepEqual from "deep-equal"; import * as fs from "fs"; import path from "path"; import YAML from "yaml"; -import { BuilderError } from "../errors/errors"; -import { ERRORS } from "../errors/errors-list"; import { AssetScriptMap, Checkpoint, @@ -204,7 +203,7 @@ export function persistCheckpoint (scriptName: string, checkpoint: Checkpoints): export async function registerCheckpoints ( deployer: Deployer, txns: Transaction[], - txIdxMap: Map + txIdxMap: Map ): Promise { for (const [idx, txn] of txns.entries()) { let txConfirmation; @@ -239,7 +238,7 @@ export async function registerCheckpoints ( txConfirmation = await deployer.waitForConfirmation(txn.txID()); const key = deployer.checkpoint.getAppCheckpointKeyFromIndex(txn.appIndex); if (key) { - const temp: rtypes.SSCInfo | undefined = deployer.checkpoint.getSSCfromCPKey(key); + const temp: rtypes.SSCInfo | undefined = deployer.checkpoint.getAppfromCPKey(key); if (txn.appOnComplete === Number(rtypes.TxnOnComplete.DeleteApplication) && temp) { temp.deleted = true; deployer.registerSSCInfo(key, temp); @@ -256,7 +255,7 @@ export async function registerCheckpoints ( timestamp: Math.round(+new Date() / 1000), deleted: false }; - const val = deployer.checkpoint.getSSCfromCPKey(res[0]); + const val = deployer.checkpoint.getAppfromCPKey(res[0]); if (val?.appID === sscInfo.appID) { deployer.logTx("Updating SSC: " + res[0], txConfirmation); } else { @@ -371,7 +370,7 @@ export class CheckpointFunctionsImpl implements CheckpointFunctions { * @param key Key here is clear program name appended to approval program name * with hypen("-") in between (approvalProgramName-clearProgramName) */ - getSSCfromCPKey (key: string): rtypes.SSCInfo | undefined { + getAppfromCPKey (key: string): rtypes.SSCInfo | undefined { const resultMap = this.cpData.precedingCP[this.networkName]?.ssc ?? new Map(); const nestedMap: any = resultMap.get(key); diff --git a/packages/algob/src/lib/tx.ts b/packages/algob/src/lib/tx.ts index 0c69a4761..842594fae 100644 --- a/packages/algob/src/lib/tx.ts +++ b/packages/algob/src/lib/tx.ts @@ -1,4 +1,5 @@ -import { encodeNote, mkTransaction, types as rtypes } from "@algo-builder/runtime"; +import { types as rtypes } from "@algo-builder/runtime"; +import { tx as webTx, types as wtypes } from "@algo-builder/web"; import algosdk, { Algodv2, SuggestedParams, Transaction } from "algosdk"; import { Deployer } from "../types"; @@ -49,17 +50,17 @@ export async function mkTxParams ( * @param txSuggestedParams suggested transaction params */ export function makeAssetCreateTxn ( - name: string, asaDef: rtypes.ASADef, + name: string, asaDef: wtypes.ASADef, flags: rtypes.ASADeploymentFlags, txSuggestedParams: SuggestedParams ): Transaction { // If TxParams has noteb64 or note , it gets precedence let note; if (flags.noteb64 ?? flags.note) { // TxParams note - note = encodeNote(flags.note, flags.noteb64); + note = webTx.encodeNote(flags.note, flags.noteb64); } else if (asaDef.noteb64 ?? asaDef.note) { // ASA definition note - note = encodeNote(asaDef.note, asaDef.noteb64); + note = webTx.encodeNote(asaDef.note, asaDef.noteb64); } // https://github.com/algorand/docs/blob/master/examples/assets/v2/javascript/AssetExample.js#L104 @@ -93,14 +94,14 @@ export function makeASAOptInTx ( params: SuggestedParams, payFlags: rtypes.TxParams ): Transaction { - const execParam: rtypes.ExecParams = { - type: rtypes.TransactionType.OptInASA, - sign: rtypes.SignType.SecretKey, + const execParam: wtypes.ExecParams = { + type: wtypes.TransactionType.OptInASA, + sign: wtypes.SignType.SecretKey, fromAccount: { addr: addr, sk: new Uint8Array(0) }, assetID: assetID, payFlags: payFlags }; - return mkTransaction(execParam, params); + return webTx.mkTransaction(execParam, params); } /** @@ -108,12 +109,12 @@ export function makeASAOptInTx ( * @param txn unsigned transaction * @param execParams transaction execution parametrs */ -function signTransaction (txn: Transaction, execParams: rtypes.ExecParams): Uint8Array { +function signTransaction (txn: Transaction, execParams: wtypes.ExecParams): Uint8Array { switch (execParams.sign) { - case rtypes.SignType.SecretKey: { + case wtypes.SignType.SecretKey: { return txn.signTxn(execParams.fromAccount.sk); } - case rtypes.SignType.LogicSignature: { + case wtypes.SignType.LogicSignature: { execParams.lsig.args = execParams.args ?? []; return algosdk.signLogicSigTransactionObject(txn, execParams.lsig).blob; } @@ -124,7 +125,7 @@ function signTransaction (txn: Transaction, execParams: rtypes.ExecParams): Uint } /** - * Make transaction parameters and update deployASA, deploySSC & ModifyAsset params + * Make transaction parameters and update deployASA, deployApp & ModifyAsset params * @param deployer Deployer object * @param txn Execution parameters * @param index index of current execParam @@ -133,25 +134,25 @@ function signTransaction (txn: Transaction, execParams: rtypes.ExecParams): Uint /* eslint-disable sonarjs/cognitive-complexity */ async function mkTx ( deployer: Deployer, - txn: rtypes.ExecParams, + txn: wtypes.ExecParams, index: number, - txIdxMap: Map + txIdxMap: Map ): Promise { // if execParams for ASA related transaction have assetID as asaName, // then set to assetIndex using info from checkpoint switch (txn.type) { - case rtypes.TransactionType.OptInASA : - case rtypes.TransactionType.TransferAsset : - case rtypes.TransactionType.ModifyAsset : - case rtypes.TransactionType.FreezeAsset : - case rtypes.TransactionType.RevokeAsset : { + case wtypes.TransactionType.OptInASA : + case wtypes.TransactionType.TransferAsset : + case wtypes.TransactionType.ModifyAsset : + case wtypes.TransactionType.FreezeAsset : + case wtypes.TransactionType.RevokeAsset : { if (typeof txn.assetID === "string") { const asaInfo = deployer.getASAInfo(txn.assetID); txn.assetID = asaInfo.assetIndex; } break; } - case rtypes.TransactionType.DestroyAsset : { + case wtypes.TransactionType.DestroyAsset : { if (typeof txn.assetID === "string") { txIdxMap.set(index, [txn.assetID, deployer.getASADef(txn.assetID, {})]); const asaInfo = deployer.getASAInfo(txn.assetID); @@ -162,14 +163,14 @@ async function mkTx ( } switch (txn.type) { - case rtypes.TransactionType.DeployASA: { + case wtypes.TransactionType.DeployASA: { deployer.assertNoAsset(txn.asaName); const asaDef = deployer.getASADef(txn.asaName, txn.asaDef); txn.asaDef = asaDef; if (txn.asaDef) txIdxMap.set(index, [txn.asaName, asaDef]); break; } - case rtypes.TransactionType.DeploySSC: { + case wtypes.TransactionType.DeployApp: { const name = String(txn.approvalProgram) + "-" + String(txn.clearProgram); deployer.assertNoAsset(name); const approval = await deployer.ensureCompiled(txn.approvalProgram); @@ -179,7 +180,7 @@ async function mkTx ( txIdxMap.set(index, [name, { total: 1, decimals: 1, unitName: "MOCK" }]); break; } - case rtypes.TransactionType.UpdateSSC: { + case wtypes.TransactionType.UpdateApp: { const cpKey = String(txn.newApprovalProgram) + "-" + String(txn.newClearProgram); const approval = await deployer.ensureCompiled(txn.newApprovalProgram); const clear = await deployer.ensureCompiled(txn.newClearProgram); @@ -188,7 +189,7 @@ async function mkTx ( txIdxMap.set(index, [cpKey, { total: 1, decimals: 1, unitName: "MOCK" }]); break; } - case rtypes.TransactionType.ModifyAsset: { + case wtypes.TransactionType.ModifyAsset: { // fetch asset mutable properties from network and set them (if they are not passed) // before modifying asset const assetInfo = await deployer.getAssetByID(BigInt(txn.assetID)); @@ -209,7 +210,7 @@ async function mkTx ( } const suggestedParams = await getSuggestedParams(deployer.algodClient); - return mkTransaction(txn, + return webTx.mkTransaction(txn, await mkTxParams(deployer.algodClient, txn.payFlags, Object.assign({}, suggestedParams))); } @@ -221,13 +222,13 @@ async function mkTx ( */ export async function executeTransaction ( deployer: Deployer, - execParams: rtypes.ExecParams | rtypes.ExecParams[]): + execParams: wtypes.ExecParams | wtypes.ExecParams[]): Promise { deployer.assertCPNotDeleted(execParams); try { let signedTxn; let txns: Transaction[] = []; - const txIdxMap = new Map(); + const txIdxMap = new Map(); if (Array.isArray(execParams)) { if (execParams.length > 16) { throw new Error("Maximum size of an atomic transfer group is 16"); } diff --git a/packages/algob/src/runtime.ts b/packages/algob/src/runtime.ts index 61ad28926..be98635b7 100644 --- a/packages/algob/src/runtime.ts +++ b/packages/algob/src/runtime.ts @@ -1,11 +1,11 @@ +import { types as rtypes } from "@algo-builder/runtime"; import { - mkTransaction, - parseSSCAppArgs, + tx as webTx, types -} from "@algo-builder/runtime"; +} from "@algo-builder/web"; export { - mkTransaction, - parseSSCAppArgs, - types + webTx, + types, + rtypes }; diff --git a/packages/algob/src/types.ts b/packages/algob/src/types.ts index 9a388d6e8..203d6fa74 100644 --- a/packages/algob/src/types.ts +++ b/packages/algob/src/types.ts @@ -1,4 +1,5 @@ import { types as rtypes } from "@algo-builder/runtime"; +import { types as wtypes } from "@algo-builder/web"; import type { LogicSig } from "algosdk"; import * as algosdk from "algosdk"; @@ -373,7 +374,7 @@ export interface AssetScriptMap { export interface CheckpointFunctions { /** * Queries a stateful smart contract info from checkpoint using key. */ - getSSCfromCPKey: (key: string) => rtypes.SSCInfo | undefined + getAppfromCPKey: (key: string) => rtypes.SSCInfo | undefined /** * Returns SSC checkpoint key using application index, @@ -426,7 +427,7 @@ export interface Deployer { deployASA: ( name: string, flags: rtypes.ASADeploymentFlags, - asaParams?: Partial + asaParams?: Partial ) => Promise /** @@ -434,11 +435,11 @@ export interface Deployer { * NOTE: This function returns "deployed" ASADef, as immutable properties * of asaDef could be updated during tx execution (eg. update asset clawback) * @name ASA name - name of ASA in the /assets/asa.yaml file */ - loadASADef: (asaName: string) => rtypes.ASADef | undefined + loadASADef: (asaName: string) => wtypes.ASADef | undefined assertNoAsset: (name: string) => void - getASADef: (name: string, asaParams?: Partial) => rtypes.ASADef + getASADef: (name: string, asaParams?: Partial) => wtypes.ASADef persistCP: () => void @@ -485,15 +486,15 @@ export interface Deployer { * Deploys stateful smart contract. * @approvalProgram approval program filename (must be present in assets folder) * @clearProgram clear program filename (must be present in assets folder) - * @flags SSCDeploymentFlags + * @flags AppDeploymentFlags * @payFlags Transaction Parameters * @scTmplParams Smart contract template parameters * (used only when compiling PyTEAL to TEAL) */ - deploySSC: ( + deployApp: ( approvalProgram: string, clearProgram: string, - flags: rtypes.SSCDeploymentFlags, + flags: rtypes.AppDeploymentFlags, payFlags: rtypes.TxParams, scTmplParams?: SCParams) => Promise @@ -506,13 +507,13 @@ export interface Deployer { * @param newClearProgram New Clear Program filename * @param flags Optional parameters to SSC (accounts, args..) */ - updateSSC: ( + updateApp: ( sender: algosdk.Account, payFlags: rtypes.TxParams, appID: number, newApprovalProgram: string, newClearProgram: string, - flags: rtypes.SSCOptionalFlags + flags: rtypes.AppOptionalFlags ) => Promise /** @@ -551,11 +552,11 @@ export interface Deployer { * @param payFlags Transaction flags * @param flags Optional parameters to SSC (accounts, args..) */ - optInAccountToSSC: ( + optInAccountToApp: ( sender: rtypes.Account, appID: number, payFlags: rtypes.TxParams, - flags: rtypes.SSCOptionalFlags) => Promise + flags: rtypes.AppOptionalFlags) => Promise /** * Opt-In to stateful smart contract (SSC) for a contract account @@ -565,11 +566,11 @@ export interface Deployer { * @param payFlags Transaction flags * @param flags Optional parameters to SSC (accounts, args..) */ - optInLsigToSSC: ( + optInLsigToApp: ( appID: number, lsig: LogicSig, payFlags: rtypes.TxParams, - flags: rtypes.SSCOptionalFlags) => Promise + flags: rtypes.AppOptionalFlags) => Promise /** * Create an entry in a script log (stored in artifacts/scripts/.log) file. */ @@ -581,7 +582,7 @@ export interface Deployer { /** * Queries a stateful smart contract info from checkpoint. */ - getSSC: (nameApproval: string, nameClear: string) => rtypes.SSCInfo | undefined + getApp: (nameApproval: string, nameClear: string) => rtypes.SSCInfo | undefined /** * Queries a delegated logic signature from checkpoint. */ @@ -610,7 +611,7 @@ export interface Deployer { * throw error(except for opt-out transactions), else pass * @param execParams Transaction execution parameters */ - assertCPNotDeleted: (execParams: rtypes.ExecParams | rtypes.ExecParams[]) => void + assertCPNotDeleted: (execParams: wtypes.ExecParams | wtypes.ExecParams[]) => void } // ************************ diff --git a/packages/algob/test/builtin-tasks/deploy.ts b/packages/algob/test/builtin-tasks/deploy.ts index d6d1e9810..4e21f19a5 100644 --- a/packages/algob/test/builtin-tasks/deploy.ts +++ b/packages/algob/test/builtin-tasks/deploy.ts @@ -1,9 +1,9 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; import * as fs from "fs"; import { executeDeployTask as executeDeployTaskNoCLI, loadFilenames } from "../../src/builtin-tasks/deploy"; import { TASK_DEPLOY, TASK_RUN } from "../../src/builtin-tasks/task-names"; -import { ERRORS } from "../../src/errors/errors-list"; import { loadCheckpoint } from "../../src/lib/script-checkpoints"; import { expectBuilderErrorAsync } from "../helpers/errors"; import { testFixtureOutputFile, useCleanFixtureProject } from "../helpers/project"; diff --git a/packages/algob/test/builtin-tasks/run.ts b/packages/algob/test/builtin-tasks/run.ts index 94d1d5f79..174d88acb 100644 --- a/packages/algob/test/builtin-tasks/run.ts +++ b/packages/algob/test/builtin-tasks/run.ts @@ -1,10 +1,10 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; import fs from "fs"; import { splitAfter } from "../../src/builtin-tasks/run"; // import * as fsExtra from "fs-extra"; import { TASK_DEPLOY, TASK_RUN } from "../../src/builtin-tasks/task-names"; -import { ERRORS } from "../../src/errors/errors-list"; import { loadCheckpoint } from "../../src/lib/script-checkpoints"; import { useEnvironment } from "../helpers/environment"; import { expectBuilderErrorAsync } from "../helpers/errors"; diff --git a/packages/algob/test/builtin-tasks/test.ts b/packages/algob/test/builtin-tasks/test.ts index 09c93e196..cc0fdc171 100644 --- a/packages/algob/test/builtin-tasks/test.ts +++ b/packages/algob/test/builtin-tasks/test.ts @@ -1,9 +1,9 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; import path from "path"; import { TASK_TEST } from "../../build/builtin-tasks/task-names"; import { loadFilenames } from "../../src/builtin-tasks/deploy"; -import { ERRORS } from "../../src/errors/errors-list"; import { expectBuilderError } from "../helpers/errors"; import { useCleanFixtureProject } from "../helpers/project"; diff --git a/packages/algob/test/fixture-projects/nested-node-project/project/nested-caller-package-tester.ts b/packages/algob/test/fixture-projects/nested-node-project/project/nested-caller-package-tester.ts index 41517fee2..2076cd1ec 100644 --- a/packages/algob/test/fixture-projects/nested-node-project/project/nested-caller-package-tester.ts +++ b/packages/algob/test/fixture-projects/nested-node-project/project/nested-caller-package-tester.ts @@ -1,4 +1,5 @@ -import { getClosestCallerPackage } from "../../../../src/internal/util/caller-package"; +import { getClosestCallerPackage } from "@algo-builder/web"; + import { call as callFromTop, callFromNestedModule as topCallFromNestedModule diff --git a/packages/algob/test/fixture-projects/nested-node-project/top-caller-package-tester.ts b/packages/algob/test/fixture-projects/nested-node-project/top-caller-package-tester.ts index 257c8c1ba..380a28bd8 100644 --- a/packages/algob/test/fixture-projects/nested-node-project/top-caller-package-tester.ts +++ b/packages/algob/test/fixture-projects/nested-node-project/top-caller-package-tester.ts @@ -1,4 +1,5 @@ -import { getClosestCallerPackage } from "../../../src/internal/util/caller-package"; +import { getClosestCallerPackage } from "@algo-builder/web"; + import { call as callFromNested, callFromTopModule as nestedCallFromTopModule diff --git a/packages/algob/test/helpers/environment.ts b/packages/algob/test/helpers/environment.ts index 664df856a..08ead8d3a 100644 --- a/packages/algob/test/helpers/environment.ts +++ b/packages/algob/test/helpers/environment.ts @@ -1,7 +1,6 @@ +import { BuilderError, ERRORS } from "@algo-builder/web"; import debug from "debug"; -import { BuilderError } from "../../src/errors/errors"; -import { ERRORS } from "../../src/errors/errors-list"; import { BuilderContext } from "../../src/internal/context"; import { loadConfigAndTasks } from "../../src/internal/core/config/config-loading"; import { ALGOB_PARAM_DEFINITIONS } from "../../src/internal/core/params/builder-params"; diff --git a/packages/algob/test/helpers/errors.ts b/packages/algob/test/helpers/errors.ts index 000b22a37..3f5a494b0 100644 --- a/packages/algob/test/helpers/errors.ts +++ b/packages/algob/test/helpers/errors.ts @@ -1,8 +1,6 @@ +import { BuilderError, ErrorDescriptor } from "@algo-builder/web"; import { assert, AssertionError } from "chai"; -import { BuilderError } from "../../src/errors/errors"; -import { ErrorDescriptor } from "../../src/errors/errors-list"; - export async function expectErrorAsync ( f: () => Promise, matchMessage?: string | RegExp @@ -62,7 +60,7 @@ export function expectBuilderError ( return; } throw new AssertionError( // eslint-disable-line @typescript-eslint/no-throw-literal - `BuilderError number ${errorDescriptor.number} expected, but no Error was thrown` + `BuilderError number ${errorDescriptor.number} expected, but no Error was thrown` // eslint-disable-line @typescript-eslint/restrict-template-expressions ); } @@ -75,7 +73,7 @@ export async function expectBuilderErrorAsync ( // This makes things easier, at least as long as we don't have async stack // traces. This may change in the near-ish future. const error = new AssertionError( - `BuilderError number ${errorDescriptor.number} expected, but no Error was thrown` + `BuilderError number ${errorDescriptor.number} expected, but no Error was thrown` // eslint-disable-line @typescript-eslint/restrict-template-expressions ); const match = String(matchMessage); diff --git a/packages/algob/test/internal/cli/arguments-parser.ts b/packages/algob/test/internal/cli/arguments-parser.ts index ce7ab0204..7d3aeaaa9 100644 --- a/packages/algob/test/internal/cli/arguments-parser.ts +++ b/packages/algob/test/internal/cli/arguments-parser.ts @@ -1,7 +1,7 @@ /* tslint:disable:no-string-literal */ // TODO this is for unit testing priv methods. We shouldn't test these at all? +import { ErrorDescriptor, ERRORS } from "@algo-builder/web"; import { assert } from "chai"; -import { ErrorDescriptor, ERRORS } from "../../../src/errors/errors-list"; import { ArgumentsParser } from "../../../src/internal/cli/arguments-parser"; import { boolean, diff --git a/packages/algob/test/internal/context.ts b/packages/algob/test/internal/context.ts index 4a44ab43f..2ba6732c6 100644 --- a/packages/algob/test/internal/context.ts +++ b/packages/algob/test/internal/context.ts @@ -1,6 +1,6 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; -import { ERRORS } from "../../src/errors/errors-list"; import { BuilderContext } from "../../src/internal/context"; import { resetBuilderContext } from "../../src/internal/reset"; import { useEnvironment } from "../helpers/environment"; diff --git a/packages/algob/test/internal/core/config/config-loading.ts b/packages/algob/test/internal/core/config/config-loading.ts index 10e71b102..644f06f23 100644 --- a/packages/algob/test/internal/core/config/config-loading.ts +++ b/packages/algob/test/internal/core/config/config-loading.ts @@ -1,4 +1,5 @@ import { types as rtypes } from "@algo-builder/runtime"; +import { ERRORS } from "@algo-builder/web"; import { Kmd } from "algosdk"; import { assert } from "chai"; import path from "path"; @@ -12,7 +13,6 @@ import { TASK_RUN, TASK_TEST } from "../../../../src/builtin-tasks/task-names"; -import { ERRORS } from "../../../../src/errors/errors-list"; import { BuilderContext } from "../../../../src/internal/context"; import { loadConfigAndTasks, loadKMDAccounts } from "../../../../src/internal/core/config/config-loading"; import { resetBuilderContext } from "../../../../src/internal/reset"; diff --git a/packages/algob/test/internal/core/config/config-validation.ts b/packages/algob/test/internal/core/config/config-validation.ts index 81e4f3efe..0e4fe8ff3 100644 --- a/packages/algob/test/internal/core/config/config-validation.ts +++ b/packages/algob/test/internal/core/config/config-validation.ts @@ -1,7 +1,7 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; import deepmerge from "deepmerge"; -import { ERRORS } from "../../../../src/errors/errors-list"; import { ALGOB_CHAIN_NAME } from "../../../../src/internal/constants"; import { getValidationErrors, diff --git a/packages/algob/test/internal/core/errors.ts b/packages/algob/test/internal/core/errors.ts index 3df4be71a..fbeafbc5c 100644 --- a/packages/algob/test/internal/core/errors.ts +++ b/packages/algob/test/internal/core/errors.ts @@ -1,13 +1,11 @@ -import { assert } from "chai"; - -import { - BuilderError, BuilderPluginError -} from "../../../src/errors/errors"; import { + BuilderError, BuilderPluginError, ERROR_RANGES, ErrorDescriptor, ERRORS -} from "../../../src/errors/errors-list"; +} from "@algo-builder/web"; +import { assert } from "chai"; + import { unsafeObjectKeys } from "../../../src/internal/util/unsafe"; // import { expectBuilderError } from "../../helpers/errors"; @@ -62,7 +60,7 @@ describe("BuilderError", () => { it("should have the right error message", () => { const error = new BuilderError(mockErrorDescriptor); - assert.equal(error.message, `ABLDR123: ${mockErrorDescriptor.message}`); + assert.equal(error.message, `ABLDR123: ${mockErrorDescriptor.message}`); // eslint-disable-line @typescript-eslint/restrict-template-expressions }); it("should format the error message with the template params", () => { @@ -249,8 +247,8 @@ describe("BuilderPluginError", () => { const error = new BuilderPluginError(message, parent); - // This is being called from mocha, so that would be used as plugin name - assert.equal(error.pluginName, "mocha"); + // This is being called from @algo-builder/algob, so that would be used as plugin name + assert.equal(error.pluginName, "@algo-builder/algob"); }); it("Should work with instanceof", () => { diff --git a/packages/algob/test/internal/core/params/argument-types.ts b/packages/algob/test/internal/core/params/argument-types.ts index 1335b137d..cdf6a0a5f 100644 --- a/packages/algob/test/internal/core/params/argument-types.ts +++ b/packages/algob/test/internal/core/params/argument-types.ts @@ -1,10 +1,10 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; import chalk from "chalk"; import * as fsExtra from "fs-extra"; import * as os from "os"; import * as path from "path"; -import { ERRORS } from "../../../../src/errors/errors-list"; import * as types from "../../../../src/internal/core/params/argument-types"; import { expectBuilderError } from "../../../helpers/errors"; diff --git a/packages/algob/test/internal/core/params/env-variables.ts b/packages/algob/test/internal/core/params/env-variables.ts index 645a9c9b6..1f3cc0f82 100644 --- a/packages/algob/test/internal/core/params/env-variables.ts +++ b/packages/algob/test/internal/core/params/env-variables.ts @@ -1,6 +1,6 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; -import { ERRORS } from "../../../../src/errors/errors-list"; import { ALGOB_PARAM_DEFINITIONS } from "../../../../src/internal/core/params/builder-params"; import { getEnvRuntimeArgs, diff --git a/packages/algob/test/internal/core/plugins.ts b/packages/algob/test/internal/core/plugins.ts index ace36f459..1f89b2d0d 100644 --- a/packages/algob/test/internal/core/plugins.ts +++ b/packages/algob/test/internal/core/plugins.ts @@ -1,7 +1,7 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; import path from "path"; -import { ERRORS } from "../../../src/errors/errors-list"; import { BuilderContext } from "../../../src/internal/context"; import { loadPluginFile, diff --git a/packages/algob/test/internal/core/runtime-environment.ts b/packages/algob/test/internal/core/runtime-environment.ts index a26d01226..592a6a4db 100644 --- a/packages/algob/test/internal/core/runtime-environment.ts +++ b/packages/algob/test/internal/core/runtime-environment.ts @@ -1,9 +1,9 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; import * as path from "path"; import * as sinon from "sinon"; import { types } from "../../../src/config"; -import { ERRORS } from "../../../src/errors/errors-list"; import { BuilderContext } from "../../../src/internal/context"; import { Environment } from "../../../src/internal/core/runtime-environment"; import { TasksDSL } from "../../../src/internal/core/tasks/dsl"; diff --git a/packages/algob/test/internal/core/tasks/dsl.ts b/packages/algob/test/internal/core/tasks/dsl.ts index 649b9bf2f..a59f397b1 100644 --- a/packages/algob/test/internal/core/tasks/dsl.ts +++ b/packages/algob/test/internal/core/tasks/dsl.ts @@ -1,6 +1,6 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; -import { ERRORS } from "../../../../src/errors/errors-list"; import { TasksDSL } from "../../../../src/internal/core/tasks/dsl"; import { expectBuilderErrorAsync } from "../../../helpers/errors"; diff --git a/packages/algob/test/internal/core/tasks/task-definitions.ts b/packages/algob/test/internal/core/tasks/task-definitions.ts index 020e0d85a..6274f530c 100644 --- a/packages/algob/test/internal/core/tasks/task-definitions.ts +++ b/packages/algob/test/internal/core/tasks/task-definitions.ts @@ -1,6 +1,6 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; -import { ERRORS } from "../../../../src/errors/errors-list"; import * as types from "../../../../src/internal/core/params/argument-types"; import { OverriddenTaskDefinition, diff --git a/packages/algob/test/internal/deployer.ts b/packages/algob/test/internal/deployer.ts index 1e07f1e31..6ee6809ff 100644 --- a/packages/algob/test/internal/deployer.ts +++ b/packages/algob/test/internal/deployer.ts @@ -1,9 +1,9 @@ import { types as rtypes } from "@algo-builder/runtime"; +import { ERRORS, types as wtypes } from "@algo-builder/web"; import { generateAccount, LogicSig } from "algosdk"; import { assert } from "chai"; import { genAccounts } from "../../src/builtin-tasks/gen-accounts"; -import { ERRORS } from "../../src/errors/errors-list"; import { DeployerDeployMode } from "../../src/internal/deployer"; import { DeployerConfig } from "../../src/internal/deployer_cfg"; import { getDummyLsig } from "../../src/lib/lsig"; @@ -15,7 +15,7 @@ import { useFixtureProject } from "../helpers/project"; import { cleanupMutableData } from "../lib/script-checkpoints"; import { AlgoOperatorDryRunImpl } from "../stubs/algo-operator"; -function mkASA (): rtypes.ASADef { +function mkASA (): wtypes.ASADef { return { total: 1, decimals: 1, @@ -167,7 +167,7 @@ describe("DeployerDeployMode", () => { localBytes: 1, globalBytes: 1 }; - const sscInfo = await deployer.deploySSC("app", "clear", sscFlags, {}); + const sscInfo = await deployer.deployApp("app", "clear", sscFlags, {}); assert.deepEqual(sscInfo, { creator: "addr-1-get-address-dry-run", @@ -198,7 +198,7 @@ describe("DeployerDeployMode", () => { deleted: false }); - const updatedInfo = await deployer.updateSSC(deployer.accounts[0], {}, 33, "app", "clear", {}); + const updatedInfo = await deployer.updateApp(deployer.accounts[0], {}, 33, "app", "clear", {}); assert.deepEqual(updatedInfo, { creator: "addr-1-get-address-dry-run", @@ -321,7 +321,7 @@ describe("DeployerDeployMode", () => { txId: "", confirmedRound: 0, assetIndex: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }) .registerSSC(networkName, "ASC name", { @@ -400,7 +400,7 @@ describe("DeployerDeployMode", () => { txId: "", confirmedRound: 0, assetIndex: 1337, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }); assert.deepEqual(deployer.asa, new Map()); diff --git a/packages/algob/test/internal/util/lazy.ts b/packages/algob/test/internal/util/lazy.ts index 367c6a173..3f1771f38 100644 --- a/packages/algob/test/internal/util/lazy.ts +++ b/packages/algob/test/internal/util/lazy.ts @@ -1,6 +1,6 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; -import { ERRORS } from "../../../src/errors/errors-list"; import { lazyFunction, lazyObject } from "../../../src/internal/util/lazy"; import { expectBuilderError } from "../../helpers/errors"; diff --git a/packages/algob/test/internal/util/scripts-runner.ts b/packages/algob/test/internal/util/scripts-runner.ts index db3f00aa1..13fb0adba 100644 --- a/packages/algob/test/internal/util/scripts-runner.ts +++ b/packages/algob/test/internal/util/scripts-runner.ts @@ -1,7 +1,7 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; import fs from "fs"; -import { ERRORS } from "../../../src/errors/errors-list"; import { DeployerRunMode } from "../../../src/internal/deployer"; import { DeployerConfig } from "../../../src/internal/deployer_cfg"; import { diff --git a/packages/algob/test/lib/files.ts b/packages/algob/test/lib/files.ts index 7c1c01286..9275e0568 100644 --- a/packages/algob/test/lib/files.ts +++ b/packages/algob/test/lib/files.ts @@ -1,6 +1,6 @@ +import { ERRORS } from "@algo-builder/web"; import { assert } from "chai"; -import { ERRORS } from "../../src/errors/errors-list"; import { assertDirChildren, assertDirectDirChildren } from "../../src/lib/files"; import { expectBuilderError } from "../helpers/errors"; diff --git a/packages/algob/test/lib/script-checkpoints.ts b/packages/algob/test/lib/script-checkpoints.ts index 25af1a44f..51557c761 100644 --- a/packages/algob/test/lib/script-checkpoints.ts +++ b/packages/algob/test/lib/script-checkpoints.ts @@ -1,9 +1,9 @@ import { types as rtypes } from "@algo-builder/runtime"; +import { ERRORS, types as wtypes } from "@algo-builder/web"; import type { LogicSig } from "algosdk"; import { assert } from "chai"; import * as fs from "fs"; -import { ERRORS } from "../../src/errors/errors-list"; import { appendToCheckpoint, CheckpointImpl, @@ -90,7 +90,7 @@ describe("Checkpoint", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }); netCheckpoint.ssc.set("SSC1", nestedMap); @@ -110,7 +110,7 @@ describe("Checkpoint", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map([["SSC1", nestedMap]]), @@ -132,7 +132,7 @@ describe("Checkpoint", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }); checkpoints = appendToCheckpoint(checkpoints, "network12345", netCheckpoint2); @@ -148,7 +148,7 @@ describe("Checkpoint", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }], ["my asa 2", { @@ -156,7 +156,7 @@ describe("Checkpoint", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map([["SSC1", nestedMap]]), @@ -180,7 +180,7 @@ describe("Checkpoint", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }); appendToCheckpoint(checkpoints, "network12345", cp1); @@ -190,7 +190,7 @@ describe("Checkpoint", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }); expectBuilderError( @@ -269,7 +269,7 @@ describe("Checkpoint", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }); cp.ssc.set( @@ -283,7 +283,7 @@ describe("Checkpoint", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map([["My SSC", nestedMap]]), @@ -329,7 +329,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map(), @@ -345,7 +345,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map(), @@ -411,7 +411,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }) .putMetadata("network1", "metadata key", "metadata value"); @@ -425,7 +425,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map(), @@ -534,7 +534,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map(), @@ -556,7 +556,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map(), @@ -572,7 +572,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false } ]]), @@ -589,7 +589,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map(), @@ -703,7 +703,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }) .registerSSC("network1", "SSC name", { @@ -746,7 +746,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false } ]]), @@ -778,7 +778,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map([["SSC name", nestedMap]]), @@ -803,7 +803,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }]]), ssc: new Map([["SSC name", nestedMap]]), @@ -835,7 +835,7 @@ describe("CheckpointRepoImpl", () => { txId: "", assetIndex: 0, confirmedRound: 0, - assetDef: {} as rtypes.ASADef, + assetDef: {} as wtypes.ASADef, deleted: false }) .registerSSC("network1", "SSC name", { diff --git a/packages/algob/test/lib/tx.ts b/packages/algob/test/lib/tx.ts index 65af1ab37..96d260efb 100644 --- a/packages/algob/test/lib/tx.ts +++ b/packages/algob/test/lib/tx.ts @@ -1,4 +1,5 @@ -import { encodeNote, types } from "@algo-builder/runtime"; +import { types } from "@algo-builder/runtime"; +import { ERRORS, tx as webTx, types as wtypes } from "@algo-builder/web"; import { ConfirmedTxInfo, decodeSignedTransaction, encodeAddress, Transaction } from "algosdk"; import { assert } from "chai"; import { isArray } from "lodash"; @@ -6,7 +7,6 @@ import sinon from 'sinon'; import { TextEncoder } from "util"; import { executeTransaction } from "../../src"; -import { ERRORS } from "../../src/errors/errors"; import { DeployerDeployMode, DeployerRunMode } from "../../src/internal/deployer"; import { DeployerConfig } from "../../src/internal/deployer_cfg"; import { Deployer } from "../../src/types"; @@ -23,22 +23,22 @@ describe("Note in TxParams", () => { const noteb64 = "asdisaddas"; it("Both notes given", () => { - const result = encodeNote(note, noteb64); + const result = webTx.encodeNote(note, noteb64); assert.deepEqual(result, encoder.encode(noteb64), "noteb64 not encoded"); }); it("Only note given", () => { - const result = encodeNote(note, undefined); + const result = webTx.encodeNote(note, undefined); assert.deepEqual(result, encoder.encode(note), "note not encoded"); }); it("Only noteb64 given", () => { - const result = encodeNote(undefined, noteb64); + const result = webTx.encodeNote(undefined, noteb64); assert.deepEqual(result, encoder.encode(noteb64), "noteb64 not encoded"); }); }); -function mkASA (): types.ASADef { +function mkASA (): wtypes.ASADef { return { total: 1, decimals: 1, @@ -51,7 +51,7 @@ describe("Opt-In to ASA", () => { useFixtureProject("config-project"); let deployer: Deployer; - let execParams: types.OptInASAParam; + let execParams: wtypes.OptInASAParam; let algod: AlgoOperatorDryRunImpl; let expected: ConfirmedTxInfo; beforeEach(async () => { @@ -62,8 +62,8 @@ describe("Opt-In to ASA", () => { deployer = new DeployerDeployMode(deployerCfg); await deployer.deployASA("silver", { creator: deployer.accounts[0] }); execParams = { - type: types.TransactionType.OptInASA, - sign: types.SignType.SecretKey, + type: wtypes.TransactionType.OptInASA, + sign: wtypes.SignType.SecretKey, payFlags: {}, fromAccount: bobAcc, assetID: 1 @@ -111,9 +111,9 @@ describe("Opt-In to ASA", () => { describe("ASA modify fields", () => { useFixtureProject("config-project"); let deployer: Deployer; - let execParams: types.ModifyAssetParam; + let execParams: wtypes.ModifyAssetParam; let algod: AlgoOperatorDryRunImpl; - let assetFields: types.AssetModFields; + let assetFields: wtypes.AssetModFields; beforeEach(async () => { const env = mkEnv("network1"); algod = new AlgoOperatorDryRunImpl(); @@ -124,8 +124,8 @@ describe("ASA modify fields", () => { clawback: bobAcc.addr }; execParams = { - type: types.TransactionType.ModifyAsset, - sign: types.SignType.SecretKey, + type: wtypes.TransactionType.ModifyAsset, + sign: wtypes.SignType.SecretKey, payFlags: {}, fromAccount: bobAcc, assetID: 1, @@ -187,9 +187,9 @@ describe("Delete ASA and SSC", () => { }); it("Should delete ASA, and set delete boolean in ASAInfo", async () => { - const execParams: types.DestroyAssetParam = { - type: types.TransactionType.DestroyAsset, - sign: types.SignType.SecretKey, + const execParams: wtypes.DestroyAssetParam = { + type: wtypes.TransactionType.DestroyAsset, + sign: wtypes.SignType.SecretKey, payFlags: {}, fromAccount: bobAcc, assetID: "silver" @@ -201,9 +201,9 @@ describe("Delete ASA and SSC", () => { }); it("Should delete ASA If asset index is used, instead of asset name", async () => { - const execParams: types.DestroyAssetParam = { - type: types.TransactionType.DestroyAsset, - sign: types.SignType.SecretKey, + const execParams: wtypes.DestroyAssetParam = { + type: wtypes.TransactionType.DestroyAsset, + sign: wtypes.SignType.SecretKey, payFlags: {}, fromAccount: bobAcc, assetID: 1 @@ -215,9 +215,9 @@ describe("Delete ASA and SSC", () => { }); it("Should not fail if ASA is not in checkpoints", async () => { - const execParams: types.DestroyAssetParam = { - type: types.TransactionType.DestroyAsset, - sign: types.SignType.SecretKey, + const execParams: wtypes.DestroyAssetParam = { + type: wtypes.TransactionType.DestroyAsset, + sign: wtypes.SignType.SecretKey, payFlags: {}, fromAccount: bobAcc, assetID: 2 @@ -226,17 +226,17 @@ describe("Delete ASA and SSC", () => { }); it("Should delete SSC, set delete boolean in latest SSCInfo", async () => { - const flags: types.SSCDeploymentFlags = { + const flags: types.AppDeploymentFlags = { sender: bobAcc, localBytes: 1, localInts: 1, globalBytes: 1, globalInts: 1 }; - const info = await deployer.deploySSC("approval.teal", "clear.teal", flags, {}); - const execParams: types.SSCCallsParam = { - type: types.TransactionType.DeleteSSC, - sign: types.SignType.SecretKey, + const info = await deployer.deployApp("approval.teal", "clear.teal", flags, {}); + const execParams: wtypes.AppCallsParam = { + type: wtypes.TransactionType.DeleteApp, + sign: wtypes.SignType.SecretKey, payFlags: {}, fromAccount: bobAcc, appID: info.appID @@ -244,15 +244,15 @@ describe("Delete ASA and SSC", () => { await executeTransaction(deployer, execParams); - const res = deployer.getSSC("approval.teal", "clear.teal"); + const res = deployer.getApp("approval.teal", "clear.teal"); assert.isDefined(res); if (res) assert.equal(res.deleted, true); }); it("Should not fail if SSC is not in checkpoints", async () => { - const execParams: types.SSCCallsParam = { - type: types.TransactionType.DeleteSSC, - sign: types.SignType.SecretKey, + const execParams: wtypes.AppCallsParam = { + type: wtypes.TransactionType.DeleteApp, + sign: wtypes.SignType.SecretKey, payFlags: {}, fromAccount: bobAcc, appID: 23 @@ -280,9 +280,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact // deploy and delete asset const asaInfo = await deployer.deployASA(assetName, { creator: deployer.accounts[0] }); assetID = asaInfo.assetIndex; - const execParams: types.DestroyAssetParam = { - type: types.TransactionType.DestroyAsset, - sign: types.SignType.SecretKey, + const execParams: wtypes.DestroyAssetParam = { + type: wtypes.TransactionType.DestroyAsset, + sign: wtypes.SignType.SecretKey, payFlags: {}, fromAccount: bobAcc, assetID: 1 @@ -290,18 +290,18 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact await executeTransaction(deployer, execParams); // deploy and delete app - const flags: types.SSCDeploymentFlags = { + const flags: types.AppDeploymentFlags = { sender: bobAcc, localBytes: 1, localInts: 1, globalBytes: 1, globalInts: 1 }; - const info = await deployer.deploySSC("approval.teal", "clear.teal", flags, {}); + const info = await deployer.deployApp("approval.teal", "clear.teal", flags, {}); appID = info.appID; - const execParam: types.SSCCallsParam = { - type: types.TransactionType.DeleteSSC, - sign: types.SignType.SecretKey, + const execParam: wtypes.AppCallsParam = { + type: wtypes.TransactionType.DeleteApp, + sign: wtypes.SignType.SecretKey, payFlags: {}, fromAccount: bobAcc, appID: info.appID @@ -333,37 +333,37 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact it("should throw error with opt-in ssc functions, if ssc exist and deleted", async () => { await expectBuilderErrorAsync( - async () => await deployer.optInAccountToSSC(bobAcc, appID, {}, {}), + async () => await deployer.optInAccountToApp(bobAcc, appID, {}, {}), ERRORS.GENERAL.APP_DELETED ); await expectBuilderErrorAsync( - async () => await deployer.optInLsigToSSC(appID, mockLsig, {}, {}), + async () => await deployer.optInLsigToApp(appID, mockLsig, {}, {}), ERRORS.GENERAL.APP_DELETED ); }); it("should pass with opt-in ssc functions, if ssc doesn't exist in checkpoint", async () => { - await deployer.optInAccountToSSC(bobAcc, 122, {}, {}); + await deployer.optInAccountToApp(bobAcc, 122, {}, {}); - await deployer.optInLsigToSSC(12223, mockLsig, {}, {}); + await deployer.optInLsigToApp(12223, mockLsig, {}, {}); }); it("should throw error with update ssc function, if ssc exist and deleted", async () => { await expectBuilderErrorAsync( - async () => await deployer.updateSSC(bobAcc, {}, appID, "approval.teal", "clear.teal", {}), + async () => await deployer.updateApp(bobAcc, {}, appID, "approval.teal", "clear.teal", {}), ERRORS.GENERAL.APP_DELETED ); }); it("should pass with update ssc functions, if ssc doesn't exist in checkpoint", async () => { - await deployer.updateSSC(bobAcc, {}, 123, "approval.teal", "clear.teal", {}); + await deployer.updateApp(bobAcc, {}, 123, "approval.teal", "clear.teal", {}); }); it("should fail if user tries to opt-in through execute tx", async () => { - const execParam: types.OptInASAParam = { - type: types.TransactionType.OptInASA, - sign: types.SignType.SecretKey, + const execParam: wtypes.OptInASAParam = { + type: wtypes.TransactionType.OptInASA, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, assetID: assetID @@ -375,9 +375,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should fail if user tries to modify through execute tx", async () => { - const execParam: types.ModifyAssetParam = { - type: types.TransactionType.ModifyAsset, - sign: types.SignType.SecretKey, + const execParam: wtypes.ModifyAssetParam = { + type: wtypes.TransactionType.ModifyAsset, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, assetID: assetID, @@ -390,9 +390,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should fail if user tries to freeze through execute tx", async () => { - const execParam: types.FreezeAssetParam = { - type: types.TransactionType.FreezeAsset, - sign: types.SignType.SecretKey, + const execParam: wtypes.FreezeAssetParam = { + type: wtypes.TransactionType.FreezeAsset, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, assetID: assetID, @@ -406,9 +406,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should fail if user tries to revoke through execute tx", async () => { - const execParam: types.RevokeAssetParam = { - type: types.TransactionType.RevokeAsset, - sign: types.SignType.SecretKey, + const execParam: wtypes.RevokeAssetParam = { + type: wtypes.TransactionType.RevokeAsset, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, assetID: assetID, @@ -423,9 +423,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should fail if user tries to destroy through execute tx", async () => { - const execParam: types.DestroyAssetParam = { - type: types.TransactionType.DestroyAsset, - sign: types.SignType.SecretKey, + const execParam: wtypes.DestroyAssetParam = { + type: wtypes.TransactionType.DestroyAsset, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, assetID: assetID @@ -437,9 +437,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should fail if user tries to transfer asa through execute tx", async () => { - const execParam: types.AssetTransferParam = { - type: types.TransactionType.TransferAsset, - sign: types.SignType.SecretKey, + const execParam: wtypes.AssetTransferParam = { + type: wtypes.TransactionType.TransferAsset, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, assetID: assetID, @@ -453,9 +453,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should pass if user tries to opt-out through execute tx", async () => { - const execParam: types.AssetTransferParam = { - type: types.TransactionType.TransferAsset, - sign: types.SignType.SecretKey, + const execParam: wtypes.AssetTransferParam = { + type: wtypes.TransactionType.TransferAsset, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: { closeRemainderTo: bobAcc.addr }, assetID: assetID, @@ -466,9 +466,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should throw error if user tries to delete deleted app", async () => { - const execParam: types.SSCCallsParam = { - type: types.TransactionType.DeleteSSC, - sign: types.SignType.SecretKey, + const execParam: wtypes.AppCallsParam = { + type: wtypes.TransactionType.DeleteApp, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, appID: appID @@ -480,9 +480,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should throw error if user tries to update deleted app", async () => { - const execParam: types.UpdateSSCParam = { - type: types.TransactionType.UpdateSSC, - sign: types.SignType.SecretKey, + const execParam: wtypes.UpdateAppParam = { + type: wtypes.TransactionType.UpdateApp, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, appID: appID, @@ -496,9 +496,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should throw error if user tries to call deleted app", async () => { - const execParam: types.SSCCallsParam = { - type: types.TransactionType.CallNoOpSSC, - sign: types.SignType.SecretKey, + const execParam: wtypes.AppCallsParam = { + type: wtypes.TransactionType.CallNoOpSSC, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, appID: appID @@ -510,9 +510,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should throw error if user tries to opt-in deleted app", async () => { - const execParam: types.OptInSSCParam = { - type: types.TransactionType.OptInSSC, - sign: types.SignType.SecretKey, + const execParam: wtypes.OptInToAppParam = { + type: wtypes.TransactionType.OptInToApp, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, appID: appID @@ -524,9 +524,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should pass if user tries to opt-out deleted app", async () => { - const execParam: types.SSCCallsParam = { - type: types.TransactionType.CloseSSC, - sign: types.SignType.SecretKey, + const execParam: wtypes.AppCallsParam = { + type: wtypes.TransactionType.CloseApp, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, appID: appID @@ -536,9 +536,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact ERRORS.GENERAL.APP_DELETED ); - const execParams: types.SSCCallsParam = { - type: types.TransactionType.ClearSSC, - sign: types.SignType.SecretKey, + const execParams: wtypes.AppCallsParam = { + type: wtypes.TransactionType.ClearApp, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, appID: appID @@ -547,9 +547,9 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should pass if user tries delete app that doesn't exist in checkpoint", async () => { - const execParam: types.DestroyAssetParam = { - type: types.TransactionType.DestroyAsset, - sign: types.SignType.SecretKey, + const execParam: wtypes.DestroyAssetParam = { + type: wtypes.TransactionType.DestroyAsset, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, assetID: 123 @@ -559,17 +559,17 @@ describe("Delete ASA and SSC transaction flow(with functions and executeTransact }); it("should pass if user tries delete (asset + app) that doesn't exist in checkpoint", async () => { - const txGroup: types.ExecParams[] = [ + const txGroup: wtypes.ExecParams[] = [ { - type: types.TransactionType.DestroyAsset, - sign: types.SignType.SecretKey, + type: wtypes.TransactionType.DestroyAsset, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, assetID: 123 }, { - type: types.TransactionType.DeleteSSC, - sign: types.SignType.SecretKey, + type: wtypes.TransactionType.DeleteApp, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, payFlags: {}, appID: 12213 @@ -600,9 +600,9 @@ describe("Deploy, Delete transactions test in run mode", () => { }); it("should deploy asa in run mode", async () => { - const execParams: types.ExecParams = { - type: types.TransactionType.DeployASA, - sign: types.SignType.SecretKey, + const execParams: wtypes.ExecParams = { + type: wtypes.TransactionType.DeployASA, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, asaName: 'silver', payFlags: {} @@ -618,9 +618,9 @@ describe("Deploy, Delete transactions test in run mode", () => { }); it("should deploy application in run mode", async () => { - const execParams: types.ExecParams = { - type: types.TransactionType.DeploySSC, - sign: types.SignType.SecretKey, + const execParams: wtypes.ExecParams = { + type: wtypes.TransactionType.DeployApp, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, approvalProgram: "approval.teal", clearProgram: "clear.teal", @@ -633,14 +633,14 @@ describe("Deploy, Delete transactions test in run mode", () => { await executeTransaction(deployer, execParams); // should not be stored in checkpoint if in run mode - assert.isUndefined(deployer.getSSC("approval.teal", "clear.teal")); + assert.isUndefined(deployer.getApp("approval.teal", "clear.teal")); }); it("should delete application in run mode", async () => { deployer = new DeployerDeployMode(deployerCfg); - let execParams: types.ExecParams = { - type: types.TransactionType.DeploySSC, - sign: types.SignType.SecretKey, + let execParams: wtypes.ExecParams = { + type: wtypes.TransactionType.DeployApp, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, approvalProgram: "approval.teal", clearProgram: "clear.teal", @@ -654,8 +654,8 @@ describe("Deploy, Delete transactions test in run mode", () => { deployer = new DeployerRunMode(deployerCfg); execParams = { - type: types.TransactionType.DeleteSSC, - sign: types.SignType.SecretKey, + type: wtypes.TransactionType.DeleteApp, + sign: wtypes.SignType.SecretKey, fromAccount: bobAcc, appID: appInfo["application-index"], payFlags: {} @@ -663,7 +663,7 @@ describe("Deploy, Delete transactions test in run mode", () => { await executeTransaction(deployer, execParams); - const res = deployer.getSSC("approval.teal", "clear.teal"); + const res = deployer.getApp("approval.teal", "clear.teal"); assert.isDefined(res); assert.equal(res?.deleted, false); }); diff --git a/packages/algob/test/mocks/deployer.ts b/packages/algob/test/mocks/deployer.ts index 9be014476..fff9bd1d6 100644 --- a/packages/algob/test/mocks/deployer.ts +++ b/packages/algob/test/mocks/deployer.ts @@ -1,4 +1,5 @@ import { types as rtypes } from "@algo-builder/runtime"; +import { types as wtypes } from "@algo-builder/web"; import type { LogicSig } from "algosdk"; import * as algosdk from "algosdk"; @@ -18,7 +19,7 @@ export class FakeDeployer implements Deployer { accountsByName = new Map(); scriptName = ''; checkpoint = { - getSSCfromCPKey (key: string): rtypes.SSCInfo | undefined { + getAppfromCPKey (key: string): rtypes.SSCInfo | undefined { throw new Error("Not implemented"); }, @@ -43,7 +44,7 @@ export class FakeDeployer implements Deployer { throw new Error("Not implemented"); } - getASADef (name: string): rtypes.ASADef { + getASADef (name: string): wtypes.ASADef { throw new Error("Not implemented"); } @@ -75,11 +76,11 @@ export class FakeDeployer implements Deployer { throw new Error("Not implemented"); } - getSSC (nameApproval: string, nameClear: string): rtypes.SSCInfo | undefined { + getApp (nameApproval: string, nameClear: string): rtypes.SSCInfo | undefined { throw new Error("Not implemented"); } - getSSCfromCPKey (key: string): rtypes.SSCInfo | undefined { + getAppfromCPKey (key: string): rtypes.SSCInfo | undefined { throw new Error("Not implemented"); } @@ -114,7 +115,7 @@ export class FakeDeployer implements Deployer { throw new Error("Not implemented"); }; - loadASADef (asaName: string): rtypes.ASADef | undefined { + loadASADef (asaName: string): wtypes.ASADef | undefined { throw new Error("Not implemented"); } @@ -128,21 +129,21 @@ export class FakeDeployer implements Deployer { throw new Error("Not implemented"); } - async deploySSC ( + async deployApp ( approvalProgram: string, clearProgram: string, - flags: rtypes.SSCDeploymentFlags, + flags: rtypes.AppDeploymentFlags, payFlags: rtypes.TxParams): Promise { throw new Error("Not implemented"); } - async updateSSC ( + async updateApp ( sender: algosdk.Account, payFlags: rtypes.TxParams, appID: number, newApprovalProgram: string, newClearProgram: string, - flags: rtypes.SSCOptionalFlags + flags: rtypes.AppOptionalFlags ): Promise { throw new Error("Not implemented"); } @@ -151,7 +152,7 @@ export class FakeDeployer implements Deployer { throw new Error("Not implemented"); } - assertCPNotDeleted (execParams: rtypes.ExecParams | rtypes.ExecParams[]): void { + assertCPNotDeleted (execParams: wtypes.ExecParams | wtypes.ExecParams[]): void { throw new Error("Not implemented"); } @@ -179,15 +180,15 @@ export class FakeDeployer implements Deployer { throw new Error("Not implemented"); } - optInAccountToSSC ( + optInAccountToApp ( sender: rtypes.Account, index: number, payFlags: rtypes.TxParams, - flags: rtypes.SSCOptionalFlags): Promise { + flags: rtypes.AppOptionalFlags): Promise { throw new Error("Not implemented"); } - optInLsigToSSC ( + optInLsigToApp ( appID: number, lsig: LogicSig, - payFlags: rtypes.TxParams, flags: rtypes.SSCOptionalFlags): Promise { + payFlags: rtypes.TxParams, flags: rtypes.AppOptionalFlags): Promise { throw new Error("not implemented."); } } diff --git a/packages/algob/test/stubs/algo-operator.ts b/packages/algob/test/stubs/algo-operator.ts index bebf897cd..6616d8ec6 100644 --- a/packages/algob/test/stubs/algo-operator.ts +++ b/packages/algob/test/stubs/algo-operator.ts @@ -1,4 +1,5 @@ import { types as rtypes } from "@algo-builder/runtime"; +import { types as wtypes } from "@algo-builder/web"; import type { LogicSig } from "algosdk"; import { Account, Algodv2, AssetInfo, ConfirmedTxInfo } from "algosdk"; @@ -40,7 +41,7 @@ export class AlgoOperatorDryRunImpl implements AlgoOperator { } async deployASA ( - name: string, asaDef: rtypes.ASADef, + name: string, asaDef: wtypes.ASADef, flags: rtypes.ASADeploymentFlags, accounts: rtypes.AccountMap, txnWriter: txWriter): Promise { return { @@ -63,10 +64,10 @@ export class AlgoOperatorDryRunImpl implements AlgoOperator { }; } - async deploySSC ( + async deployApp ( approvalProgram: string, clearProgram: string, - flags: rtypes.SSCDeploymentFlags, + flags: rtypes.AppDeploymentFlags, payFlags: rtypes.TxParams, txWriter: txWriter, scInitParam?: unknown): Promise { @@ -80,13 +81,13 @@ export class AlgoOperatorDryRunImpl implements AlgoOperator { }; } - async updateSSC ( + async updateApp ( sender: Account, payFlags: rtypes.TxParams, appID: number, newApprovalProgram: string, newClearProgram: string, - flags: rtypes.SSCOptionalFlags, + flags: rtypes.AppOptionalFlags, txWriter: txWriter ): Promise { return { @@ -122,20 +123,20 @@ export class AlgoOperatorDryRunImpl implements AlgoOperator { return new Promise((resolve, reject) => { resolve(); }); } - optInAccountToSSC ( + optInAccountToApp ( sender: rtypes.Account, index: number, - payFlags: rtypes.TxParams, flags: rtypes.SSCOptionalFlags): Promise { + payFlags: rtypes.TxParams, flags: rtypes.AppOptionalFlags): Promise { return new Promise((resolve, reject) => { resolve(); }); } - optInLsigToSSC ( + optInLsigToApp ( appID: number, lsig: LogicSig, - payFlags: rtypes.TxParams, flags: rtypes.SSCOptionalFlags): Promise { + payFlags: rtypes.TxParams, flags: rtypes.AppOptionalFlags): Promise { return new Promise((resolve, reject) => { resolve(); }); } optInToASAMultiple ( - asaName: string, asaDef: rtypes.ASADef, + asaName: string, asaDef: wtypes.ASADef, flags: rtypes.ASADeploymentFlags, accounts: rtypes.AccountMap, assetIndex: number ): Promise { return Promise.resolve(); diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 0ebc7b9b4..977f64863 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -63,6 +63,7 @@ "sinon": "^9.0.2" }, "dependencies": { + "@algo-builder/web": "0.0.1", "@types/lodash.clonedeep": "^4.5.6", "algosdk": "^1.9.1", "glob": "^7.1.6", diff --git a/packages/runtime/src/account.ts b/packages/runtime/src/account.ts index 1ec7b318a..e8e7ee0db 100644 --- a/packages/runtime/src/account.ts +++ b/packages/runtime/src/account.ts @@ -1,3 +1,4 @@ +import { types } from "@algo-builder/web"; import type { Account, AssetDef, @@ -17,8 +18,8 @@ import { keyToBytes } from "./lib/parsing"; import { assertValidSchema } from "./lib/stateful"; import { AccountStoreI, - AppLocalStateM, ASADef, AssetHoldingM, AssetModFields, CreatedAppM, SSCAttributesM, - SSCDeploymentFlags, StackElem + AppDeploymentFlags, AppLocalStateM, AssetHoldingM, CreatedAppM, SSCAttributesM, + StackElem } from "./types"; const StateMap = "key-value"; @@ -175,7 +176,7 @@ export class AccountStore implements AccountStoreI { * @param name Asset Name * @param asaDef Asset Definitions */ - addAsset (assetId: number, name: string, asaDef: ASADef): AssetDef { + addAsset (assetId: number, name: string, asaDef: types.ASADef): AssetDef { if (this.createdAssets.size === MAX_ALGORAND_ACCOUNT_ASSETS) { throw new RuntimeError(RUNTIME_ERRORS.ASA.MAX_LIMIT_ASSETS, { name: name, address: this.address, max: MAX_ALGORAND_ACCOUNT_ASSETS }); @@ -202,7 +203,7 @@ export class AccountStore implements AccountStoreI { * @param assetId Asset Index * @param fields Fields for modification */ - modifyAsset (assetId: number, fields: AssetModFields): void { + modifyAsset (assetId: number, fields: types.AssetModFields): void { const asset = this.getAssetDef(assetId); if (asset === undefined) { throw new RuntimeError(RUNTIME_ERRORS.ASA.ASSET_NOT_FOUND, { assetId: assetId }); @@ -269,7 +270,7 @@ export class AccountStore implements AccountStoreI { * @param clearProgram application clear program * NOTE - approval and clear program must be the TEAL code as string */ - addApp (appID: number, params: SSCDeploymentFlags, + addApp (appID: number, params: AppDeploymentFlags, approvalProgram: string, clearProgram: string): CreatedAppM { if (this.createdApps.size === MAX_ALGORAND_ACCOUNT_APPS) { throw new RuntimeError(RUNTIME_ERRORS.GENERAL.MAX_LIMIT_APPS, { @@ -372,7 +373,7 @@ class App { readonly attributes: SSCAttributesM; // NOTE - approval and clear program must be the TEAL code as string - constructor (appID: number, params: SSCDeploymentFlags, + constructor (appID: number, params: AppDeploymentFlags, approvalProgram: string, clearProgram: string) { this.id = appID; this.attributes = { @@ -391,7 +392,7 @@ class Asset { readonly id: number; readonly definitions: AssetDef; - constructor (assetId: number, def: ASADef, creator: string, assetName: string) { + constructor (assetId: number, def: types.ASADef, creator: string, assetName: string) { this.id = assetId; this.definitions = { creator: creator, diff --git a/packages/runtime/src/ctx.ts b/packages/runtime/src/ctx.ts index 6f59b3c7c..460077957 100644 --- a/packages/runtime/src/ctx.ts +++ b/packages/runtime/src/ctx.ts @@ -1,15 +1,16 @@ +import { tx as webTx, types } from "@algo-builder/web"; import { AssetDef, makeAssetTransferTxnWithSuggestedParams } from "algosdk"; -import { getFromAddress, Runtime } from "."; +import { Runtime } from "."; import { RUNTIME_ERRORS } from "./errors/errors-list"; import { RuntimeError } from "./errors/runtime-errors"; -import { ASSET_CREATION_FEE } from "./lib/constants"; import { mockSuggestedParams } from "./mock/tx"; import { - AccountAddress, AccountStoreI, AlgoTransferParam, ASADeploymentFlags, AssetHoldingM, AssetModFields, - AssetTransferParam, Context, ExecParams, ExecutionMode, - SignType, SSCAttributesM, SSCDeploymentFlags, - State, TransactionType, Txn, TxParams + AccountAddress, AccountStoreI, + AppDeploymentFlags, + ASADeploymentFlags, AssetHoldingM, + Context, ExecutionMode, + SSCAttributesM, State, Txn, TxParams } from "./types"; const APPROVAL_PROGRAM = "approval-program"; @@ -121,13 +122,13 @@ export class Ctx implements Context { } // transfer ALGO as per transaction parameters - transferAlgo (txnParam: AlgoTransferParam): void { - const fromAccount = this.getAccount(getFromAddress(txnParam)); + transferAlgo (txnParam: types.AlgoTransferParam): void { + const fromAccount = this.getAccount(webTx.getFromAddress(txnParam)); const toAccount = this.getAccount(txnParam.toAccountAddr); txnParam.amountMicroAlgos = BigInt(txnParam.amountMicroAlgos); fromAccount.amount -= txnParam.amountMicroAlgos; // remove 'x' algo from sender - toAccount.amount += txnParam.amountMicroAlgos; // add 'x' algo to receiver + toAccount.amount += BigInt(txnParam.amountMicroAlgos); // add 'x' algo to receiver this.assertAccBalAboveMin(fromAccount.address); if (txnParam.payFlags.closeRemainderTo) { @@ -202,7 +203,7 @@ export class Ctx implements Context { * - When creating or opting into an app, the minimum balance grows before the app code runs */ addApp ( - fromAccountAddr: AccountAddress, flags: SSCDeploymentFlags, + fromAccountAddr: AccountAddress, flags: AppDeploymentFlags, approvalProgram: string, clearProgram: string ): number { const senderAcc = this.getAccount(fromAccountAddr); @@ -272,8 +273,8 @@ export class Ctx implements Context { } // transfer ASSET as per transaction parameters - transferAsset (txnParam: AssetTransferParam): void { - const fromAccountAddr = getFromAddress(txnParam); + transferAsset (txnParam: types.AssetTransferParam): void { + const fromAccountAddr = webTx.getFromAddress(txnParam); const fromAssetHolding = this.getAssetHolding(txnParam.assetID as number, fromAccountAddr); const toAssetHolding = this.getAssetHolding(txnParam.assetID as number, txnParam.toAccountAddr); txnParam.amount = BigInt(txnParam.amount); @@ -291,7 +292,7 @@ export class Ctx implements Context { }); } fromAssetHolding.amount -= txnParam.amount; - toAssetHolding.amount += txnParam.amount; + toAssetHolding.amount += BigInt(txnParam.amount); if (txnParam.payFlags.closeRemainderTo) { const closeToAddr = txnParam.payFlags.closeRemainderTo; @@ -315,7 +316,7 @@ export class Ctx implements Context { * @param assetId Asset Index * @param fields Asset modifying fields */ - modifyAsset (assetId: number, fields: AssetModFields): void { + modifyAsset (assetId: number, fields: types.AssetModFields): void { const creatorAcc = this.getAssetAccount(assetId); creatorAcc.modifyAsset(assetId, fields); } @@ -448,12 +449,12 @@ export class Ctx implements Context { * @param txnParams Transaction Parameters */ /* eslint-disable sonarjs/cognitive-complexity */ - processTransactions (txnParams: ExecParams[]): void { + processTransactions (txnParams: types.ExecParams[]): void { txnParams.forEach((txnParam, idx) => { - const fromAccountAddr = getFromAddress(txnParam); + const fromAccountAddr = webTx.getFromAddress(txnParam); this.deductFee(fromAccountAddr, idx); - if (txnParam.sign === SignType.LogicSignature) { + if (txnParam.sign === types.SignType.LogicSignature) { this.tx = this.gtxs[idx]; // update current tx to index of stateless this.runtime.validateLsigAndRun(txnParam, this.debugStack); this.tx = this.gtxs[0]; // after executing stateless tx updating current tx to default (index 0) @@ -461,28 +462,28 @@ export class Ctx implements Context { // https://developer.algorand.org/docs/features/asc1/stateful/#the-lifecycle-of-a-stateful-smart-contract switch (txnParam.type) { - case TransactionType.TransferAlgo: { + case types.TransactionType.TransferAlgo: { this.transferAlgo(txnParam); break; } - case TransactionType.TransferAsset: { + case types.TransactionType.TransferAsset: { this.transferAsset(txnParam); break; } - case TransactionType.CallNoOpSSC: { + case types.TransactionType.CallNoOpSSC: { this.tx = this.gtxs[idx]; // update current tx to the requested index const appParams = this.getApp(txnParam.appID); this.runtime.run(appParams[APPROVAL_PROGRAM], ExecutionMode.APPLICATION, this.debugStack); break; } - case TransactionType.CloseSSC: { + case types.TransactionType.CloseApp: { this.tx = this.gtxs[idx]; // update current tx to the requested index const appParams = this.getApp(txnParam.appID); this.runtime.run(appParams[APPROVAL_PROGRAM], ExecutionMode.APPLICATION, this.debugStack); this.closeApp(fromAccountAddr, txnParam.appID); break; } - case TransactionType.UpdateSSC: { + case types.TransactionType.UpdateApp: { this.tx = this.gtxs[idx]; // update current tx to the requested index this.updateApp( @@ -490,7 +491,7 @@ export class Ctx implements Context { ); break; } - case TransactionType.ClearSSC: { + case types.TransactionType.ClearApp: { this.tx = this.gtxs[idx]; // update current tx to the requested index const appParams = this.runtime.assertAppDefined(txnParam.appID, this.getApp(txnParam.appID)); try { @@ -504,14 +505,14 @@ export class Ctx implements Context { this.closeApp(fromAccountAddr, txnParam.appID); // remove app from local state break; } - case TransactionType.DeleteSSC: { + case types.TransactionType.DeleteApp: { this.tx = this.gtxs[idx]; // update current tx to the requested index const appParams = this.getApp(txnParam.appID); this.runtime.run(appParams[APPROVAL_PROGRAM], ExecutionMode.APPLICATION, this.debugStack); this.deleteApp(txnParam.appID); break; } - case TransactionType.ModifyAsset: { + case types.TransactionType.ModifyAsset: { const asset = this.getAssetDef(txnParam.assetID as number); if (asset.manager !== fromAccountAddr) { throw new RuntimeError(RUNTIME_ERRORS.ASA.MANAGER_ERROR, { address: asset.manager }); @@ -520,7 +521,7 @@ export class Ctx implements Context { this.modifyAsset(txnParam.assetID as number, txnParam.fields); break; } - case TransactionType.FreezeAsset: { + case types.TransactionType.FreezeAsset: { const asset = this.getAssetDef(txnParam.assetID as number); if (asset.freeze !== fromAccountAddr) { throw new RuntimeError(RUNTIME_ERRORS.ASA.FREEZE_ERROR, { address: asset.freeze }); @@ -528,7 +529,7 @@ export class Ctx implements Context { this.freezeAsset(txnParam.assetID as number, txnParam.freezeTarget, txnParam.freezeState); break; } - case TransactionType.RevokeAsset: { + case types.TransactionType.RevokeAsset: { const asset = this.getAssetDef(txnParam.assetID as number); if (asset.clawback !== fromAccountAddr) { throw new RuntimeError(RUNTIME_ERRORS.ASA.CLAWBACK_ERROR, { address: asset.clawback }); @@ -542,7 +543,7 @@ export class Ctx implements Context { ); break; } - case TransactionType.DestroyAsset: { + case types.TransactionType.DestroyAsset: { const asset = this.getAssetDef(txnParam.assetID as number); if (asset.manager !== fromAccountAddr) { throw new RuntimeError(RUNTIME_ERRORS.ASA.MANAGER_ERROR, { address: asset.manager }); @@ -550,7 +551,7 @@ export class Ctx implements Context { this.destroyAsset(txnParam.assetID as number); break; } - case TransactionType.DeployASA: { + case types.TransactionType.DeployASA: { this.tx = this.gtxs[idx]; // update current tx to the requested index const senderAcc = this.getAccount(fromAccountAddr); const name = txnParam.asaName; @@ -562,13 +563,13 @@ export class Ctx implements Context { this.addAsset(name, fromAccountAddr, flags); break; } - case TransactionType.OptInASA: { + case types.TransactionType.OptInASA: { this.optIntoASA(txnParam.assetID as number, fromAccountAddr, txnParam.payFlags); break; } - case TransactionType.DeploySSC: { + case types.TransactionType.DeployApp: { const senderAcc = this.getAccount(fromAccountAddr); - const flags: SSCDeploymentFlags = { + const flags: AppDeploymentFlags = { sender: senderAcc.account, localInts: txnParam.localInts, localBytes: txnParam.localBytes, @@ -584,7 +585,7 @@ export class Ctx implements Context { ); break; } - case TransactionType.OptInSSC: { + case types.TransactionType.OptInToApp: { this.tx = this.gtxs[idx]; // update current tx to txn being exectuted in group this.optInToApp(fromAccountAddr, txnParam.appID); diff --git a/packages/runtime/src/errors/runtime-errors.ts b/packages/runtime/src/errors/runtime-errors.ts index 11d584cf6..4972e30c4 100644 --- a/packages/runtime/src/errors/runtime-errors.ts +++ b/packages/runtime/src/errors/runtime-errors.ts @@ -1,3 +1,5 @@ +import { applyErrorMessageTemplate } from "@algo-builder/web"; + import { AnyMap } from "../types"; import { ErrorDescriptor, getRuntimeErrorCode } from "./errors-list"; @@ -26,7 +28,7 @@ export class RuntimeError extends Error { messageArguments ); - super(prefix + formattedMessage); + super(String(prefix) + String(formattedMessage)); this.errorDescriptor = errorDescriptor; this.number = errorDescriptor.number; @@ -38,69 +40,3 @@ export class RuntimeError extends Error { Object.setPrototypeOf(this, RuntimeError.prototype); } } - -/** - * This function applies error messages templates like this: - * - * - Template is a string which contains a variable tags. A variable tag is a - * a variable name surrounded by %. Eg: %plugin1% - * - A variable name is a string of alphanumeric ascii characters. - * - Every variable tag is replaced by its value. - * - %% is replaced by %. - * - Values can't contain variable tags. - * - If a variable is not present in the template, but present in the values - * object, an error is thrown. - * - * @param template The template string. - * @param values A map of variable names to their values. - */ -export function applyErrorMessageTemplate ( - template: string, - values: { [templateVar: string]: any } // eslint-disable-line @typescript-eslint/no-explicit-any -): string { - return _applyErrorMessageTemplate(template, values); -} - -function _applyErrorMessageTemplate ( - template: string, - values: { [templateVar: string]: any } // eslint-disable-line @typescript-eslint/no-explicit-any -): string { - if (template.includes("%%")) { - return template - .split("%%") - .map((part) => _applyErrorMessageTemplate(part, values)) - .join("%"); - } - - for (const variableName of Object.keys(values)) { - let value: string; - - if (values[variableName] === undefined) { - value = "undefined"; - } else if (values[variableName] === null) { - value = "null"; - } else { - value = values[variableName].toString(); - } - - if (value === undefined) { - value = "undefined"; - } - - const variableTag = `%${variableName}%`; - template = replaceAll(template, variableTag, value); - } - - return template; -} - -/** - * Replaces all the instances of [[toReplace]] by [[replacement]] in [[str]]. - */ -export function replaceAll ( - str: string, - toReplace: string, - replacement: string -): string { - return str.split(toReplace).join(replacement); -} diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index f6b8c78b2..e484ef967 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -1,12 +1,10 @@ import { AccountStore } from "./account"; import * as ERRORS from "./errors/errors-list"; -import { applyErrorMessageTemplate } from "./errors/runtime-errors"; import { parseZodError } from "./errors/validation-errors"; import { Interpreter } from "./interpreter/interpreter"; import { loadASAFile, overrideASADef, validateASADefs } from "./lib/asa"; import { getPathFromDirRecursive, loadFromYamlFileSilent, loadFromYamlFileSilentWithMessage, lsTreeWalk } from "./lib/files"; -import { addressToPk, parseSSCAppArgs, stringToBytes, uint64ToBigEndian } from "./lib/parsing"; -import { checkIfAssetDeletionTx, encodeNote, getFromAddress, mkTransaction } from "./lib/txn"; +import { checkIfAssetDeletionTx } from "./lib/txn"; import { parser } from "./parser/parser"; import { Runtime } from "./runtime"; import * as types from "./types"; @@ -16,15 +14,7 @@ export { Interpreter, Runtime, AccountStore, - mkTransaction, checkIfAssetDeletionTx, - getFromAddress, - applyErrorMessageTemplate, - parseSSCAppArgs, - addressToPk, - uint64ToBigEndian, - stringToBytes, - encodeNote, loadFromYamlFileSilent, loadFromYamlFileSilentWithMessage, loadASAFile, diff --git a/packages/runtime/src/interpreter/opcode-list.ts b/packages/runtime/src/interpreter/opcode-list.ts index 3d5888983..15e0078a3 100644 --- a/packages/runtime/src/interpreter/opcode-list.ts +++ b/packages/runtime/src/interpreter/opcode-list.ts @@ -1,5 +1,6 @@ /* eslint sonarjs/no-identical-functions: 0 */ /* eslint sonarjs/no-duplicate-string: 0 */ +import { parsing } from "@algo-builder/web"; import { AssetDef, decodeAddress, decodeUint64, encodeAddress, encodeUint64, isValidAddress, verifyBytes } from "algosdk"; import { Message, sha256 } from "js-sha256"; import { sha512_256 } from "js-sha512"; @@ -11,7 +12,7 @@ import { compareArray } from "../lib/compare"; import { AssetParamMap, GlobalFields, MAX_CONCAT_SIZE, MAX_UINT64, MaxTEALVersion, TxArrFields } from "../lib/constants"; import { assertLen, assertOnlyDigits, convertToBuffer, - convertToString, getEncoding, parseBinaryStrToBigInt, stringToBytes + convertToString, getEncoding, parseBinaryStrToBigInt } from "../lib/parsing"; import { Stack } from "../lib/stack"; import { txAppArg, txnSpecbyField } from "../lib/txn"; @@ -231,7 +232,7 @@ export class Bytecblock extends Op { this.line = line; const bytecblock: Uint8Array[] = []; for (const val of args) { - bytecblock.push(stringToBytes(val)); + bytecblock.push(parsing.stringToBytes(val)); } this.interpreter = interpreter; @@ -2051,7 +2052,7 @@ export class GetAssetDef extends Op { if (isValidAddress(def)) { value = decodeAddress(def).publicKey; } else { - value = stringToBytes(def); + value = parsing.stringToBytes(def); } break; } diff --git a/packages/runtime/src/lib/asa.ts b/packages/runtime/src/lib/asa.ts index efcaafea2..8c8711b95 100644 --- a/packages/runtime/src/lib/asa.ts +++ b/packages/runtime/src/lib/asa.ts @@ -1,3 +1,4 @@ +import { ASADefSchema, types } from "@algo-builder/web"; import type { AssetDef } from "algosdk"; import { existsSync } from "fs"; import path from "path"; @@ -6,8 +7,7 @@ import * as z from 'zod'; import { RUNTIME_ERRORS } from "../errors/errors-list"; import { RuntimeError } from "../errors/runtime-errors"; import { parseZodError } from "../errors/validation-errors"; -import { AccountMap, ASADef, ASADefs, AssetModFields, RuntimeAccountMap } from "../types"; -import { ASADefSchema } from "../types-input"; +import { AccountMap, RuntimeAccountMap } from "../types"; import { getPathFromDirRecursive, loadFromYamlFileSilent } from "./files"; export const ASSETS_DIR = "assets"; @@ -19,7 +19,7 @@ export const ASSETS_DIR = "assets"; * @param asaDef asset definition */ function validateOptInAccNames (accounts: AccountMap | RuntimeAccountMap, - asaDef: ASADef, + asaDef: types.ASADef, source?: string): void { if (!asaDef.optInAccNames || asaDef.optInAccNames.length === 0) { return; @@ -41,7 +41,7 @@ function validateOptInAccNames (accounts: AccountMap | RuntimeAccountMap, * @param source source of assetDef: asa.yaml file OR function deployASA * @returns parsed asa definition */ -function _parseASADef (asaDef: ASADef, source?: string): ASADef { +function _parseASADef (asaDef: types.ASADef, source?: string): types.ASADef { try { const parsedDef = ASADefSchema.parse(asaDef); parsedDef.manager = parsedDef.manager !== "" ? parsedDef.manager : undefined; @@ -71,8 +71,8 @@ function _parseASADef (asaDef: ASADef, source?: string): ASADef { */ export function overrideASADef ( accounts: AccountMap, - origDef: ASADef, - newDef?: Partial): ASADef { + origDef: types.ASADef, + newDef?: Partial): types.ASADef { if (newDef === undefined) { return origDef; } const source = 'ASA deployment'; @@ -92,7 +92,7 @@ export function overrideASADef ( * @param filename asa filename */ export function validateASADefs ( - asaDefs: ASADefs, accounts: AccountMap | RuntimeAccountMap, filename: string): ASADefs { + asaDefs: types.ASADefs, accounts: AccountMap | RuntimeAccountMap, filename: string): types.ASADefs { for (const name in asaDefs) { asaDefs[name] = _parseASADef(asaDefs[name], filename); validateOptInAccNames(accounts, asaDefs[name], filename); @@ -106,7 +106,7 @@ export function validateASADefs ( * used in builder. RuntimeAccountMap is for AccountStore used in runtime * (where we use maps instead of arrays in sdk structures). */ -export function loadASAFile (accounts: AccountMap | RuntimeAccountMap): ASADefs { +export function loadASAFile (accounts: AccountMap | RuntimeAccountMap): types.ASADefs { let filePath; if (!existsSync(ASSETS_DIR)) { // to handle tests filePath = path.join(ASSETS_DIR, "asa.yaml"); @@ -130,15 +130,15 @@ function isDefined (value: string | undefined): boolean { * @param fields Custom ASA fields * @param asset Defined ASA fields */ -export function checkAndSetASAFields (fields: AssetModFields, asset: AssetDef): void { +export function checkAndSetASAFields (fields: types.AssetModFields, asset: AssetDef): void { for (const x of ['manager', 'reserve', 'freeze', 'clawback']) { - const customField = fields[x as keyof AssetModFields]; - const asaField = asset[x as keyof AssetModFields]; + const customField = fields[x as keyof types.AssetModFields]; + const asaField = asset[x as keyof types.AssetModFields]; // Check if custom field is set and defined and ASA field is blank field if (isDefined(customField) && !isDefined(asaField)) { throw new RuntimeError(RUNTIME_ERRORS.ASA.BLANK_ADDRESS_ERROR); } else if (customField !== undefined && isDefined(asaField)) { // Change if ASA field and custom field is defined - asset[x as keyof AssetModFields] = customField; + asset[x as keyof types.AssetModFields] = customField; } } } diff --git a/packages/runtime/src/lib/parsing.ts b/packages/runtime/src/lib/parsing.ts index 3eb3f5bf8..6eb192251 100644 --- a/packages/runtime/src/lib/parsing.ts +++ b/packages/runtime/src/lib/parsing.ts @@ -1,10 +1,10 @@ -import { decodeAddress, encodeUint64 } from "algosdk"; +import { parsing } from "@algo-builder/web"; import * as base32 from "hi-base32"; import { RUNTIME_ERRORS } from "../errors/errors-list"; import { RuntimeError } from "../errors/runtime-errors"; import { EncodingType } from "../types"; -import { MAX_UINT64, MIN_UINT64, reBase32, reBase64, reDigit } from "./constants"; +import { reBase32, reBase64, reDigit } from "./constants"; /** * assert if string contains digits only @@ -60,12 +60,7 @@ export function assertBase32 (str: string, line: number): void { * @param key : key in a stateful key-value pair */ export function keyToBytes (key: Uint8Array | string): Uint8Array { - return typeof key === 'string' ? stringToBytes(key) : key; -} - -// parse string to Uint8Array -export function stringToBytes (s: string): Uint8Array { - return new Uint8Array(Buffer.from(s)); + return typeof key === 'string' ? parsing.stringToBytes(key) : key; } // parse Uint8Array to string @@ -98,86 +93,6 @@ export function convertToBuffer (s: string, encoding?: EncodingType): Buffer { } } -// verify n is an unsigned 64 bit integer -function assertUint64 (n: bigint): void { - if (n < MIN_UINT64 || n > MAX_UINT64) { - throw new Error(`Invalid uint64 ${n}`); - } -} - -/** - * Converts 64 bit unsigned integer to bytes in big endian. - */ -export function uint64ToBigEndian (x: number | bigint): Uint8Array { - assertUint64(BigInt(x)); - return encodeUint64(x); -} - -/** - * Takes an Algorand address in string form and decodes it into a Uint8Array (as public key) - * @param addr : algorand address - */ -export function addressToPk (addr: string): Uint8Array { - return decodeAddress(addr).publicKey; -} - -const throwFmtError = (appArg: string): void => { - throw new Error(`Format of arguments passed to stateful smart is invalid for ${appArg}`); -}; - -/** - * Parses appArgs to bytes if arguments passed to SSC are similar to goal ('int:1', 'str:hello'..) - * https://developer.algorand.org/docs/features/asc1/stateful/#passing-arguments-to-stateful-smart-contracts - * eg. "int:1" => new Uint8Aarray([0, 0, 0, 0, 0, 0, 0, 1]) - * NOTE: parseSSCAppArgs returns undefined to handle the case when application args passed to - * stateful smart contract is undefined - * @param appArgs : arguments to stateful smart contract - */ -export function parseSSCAppArgs (appArgs?: Array): Uint8Array[] | undefined { - if (appArgs === undefined) { return undefined; } - const args = []; - - for (const appArg of appArgs) { - // if appArg already bytes, then we don't need to parse - // just push to array and continue - if (appArg instanceof Uint8Array) { - args.push(appArg); - continue; - } - const [type, value] = appArg.split(':'); // eg "int:1" => ['int', '1'] - - // if given string is not invalid, throw error - if (type === undefined || value === undefined) { throwFmtError(appArg); } - - // parse string to bytes according to type - let arg; - switch (type) { - case 'int': { - if (!reDigit.test(value)) { throwFmtError(appArg); } // verify only digits are present in string - arg = uint64ToBigEndian(BigInt(value)); - break; - } - case 'str': { - arg = stringToBytes(value); - break; - } - case 'addr': { - arg = addressToPk(value); - break; - } - case 'b64': { - arg = new Uint8Array(Buffer.from(value, 'base64')); - break; - } - default: { - throwFmtError(appArg); - } - } - args.push(arg); - }; - return args as Uint8Array[]; -} - /** * Returns string and type of encoding (base64 or base32) on string * @param arg string containg type of encoding + encoded string diff --git a/packages/runtime/src/lib/txn.ts b/packages/runtime/src/lib/txn.ts index 399b34eaf..01f67275b 100644 --- a/packages/runtime/src/lib/txn.ts +++ b/packages/runtime/src/lib/txn.ts @@ -1,12 +1,11 @@ -import type { AssetDefEnc, StateSchemaEnc, SuggestedParams, Transaction } from "algosdk"; -import algosdk from "algosdk"; +import { parsing } from "@algo-builder/web"; +import type { AssetDefEnc, StateSchemaEnc, Transaction } from "algosdk"; import { RUNTIME_ERRORS } from "../errors/errors-list"; import { RuntimeError } from "../errors/runtime-errors"; import { Op } from "../interpreter/opcode"; import { TxFieldDefaults, TxnFields } from "../lib/constants"; -import { parseSSCAppArgs, stringToBytes } from "../lib/parsing"; -import { AccountAddress, ExecParams, SignType, StackElem, TransactionType, TxField, Txn, TxnType } from "../types"; +import { StackElem, TxField, Txn, TxnType } from "../types"; const assetTxnFields = new Set([ 'ConfigAssetTotal', @@ -37,7 +36,7 @@ export function parseToStackElem (a: unknown, field: TxField): StackElem { return BigInt(a); } if (typeof a === "string") { - return stringToBytes(a); + return parsing.stringToBytes(a); } return TxFieldDefaults[field]; @@ -90,7 +89,7 @@ export function txnSpecbyField (txField: string, tx: Txn, gtxns: Txn[], tealVers break; } case 'TxID': { - return stringToBytes(tx.txID); + return parsing.stringToBytes(tx.txID); } case 'GroupIndex': { result = gtxns.indexOf(tx); @@ -163,258 +162,3 @@ export function txAppArg (txField: TxField, tx: Txn, idx: number, op: Op, op.checkIndexBound(idx, result, line); return parseToStackElem(result[idx], txField); } - -export function encodeNote (note: string | undefined, noteb64: string| undefined): Uint8Array | undefined { - if (note === undefined && noteb64 === undefined) { return undefined; } - const encoder = new TextEncoder(); - return noteb64 ? encoder.encode(noteb64) : encoder.encode(note); -} - -/** - * Returns from address from the transaction params depending on @SignType - * @param execParams transaction execution params passed by user - */ -export function getFromAddress (execParams: ExecParams): AccountAddress { - if (execParams.sign === SignType.SecretKey) { - return execParams.fromAccountAddr ?? execParams.fromAccount.addr; - } - return execParams.fromAccountAddr; -} - -/** - * Returns unsigned transaction as per ExecParams - * ExecParams can be of following types: - * + AlgoTransferParam used for transferring algo - * + AssetTransferParam used for transferring asset - * + ModifyAssetParam used to modify asset mutable properties - * + FreezeAssetParam used to freeze asset (only permitted by asa freeze account) - * + RevokeAssetParam used to revoke assets (by asset clawback) - * + DestroyAssetParam used to delete asset (by asset manager) - * + Deploy Params - deploy ASA, deploy SSC - * + OptIn Params - optInToASA, optInToSSC - * + SSCCallsParam (NoOp, Clear, Delete..)used for calling stateful smart contracts. - For more advanced use-cases, please use `algosdk.tx` directly. - NOTE: parseSSCAppArgs is used to handle case when user passes appArgs similar to goal - * @param execParams ExecParams - * @param suggestedParams blockchain transaction suggested parameters (firstRound, lastRound, fee..) - * @returns SDK Transaction object - */ -export function mkTransaction (execParams: ExecParams, suggestedParams: SuggestedParams): Transaction { - const note = encodeNote(execParams.payFlags.note, execParams.payFlags.noteb64); - const transactionType = execParams.type; - const fromAccountAddr = getFromAddress(execParams); - switch (execParams.type) { - case TransactionType.TransferAsset: { - return algosdk.makeAssetTransferTxnWithSuggestedParams( - fromAccountAddr, - execParams.toAccountAddr, - execParams.payFlags.closeRemainderTo, - undefined, - execParams.amount, - note, - execParams.assetID, - suggestedParams); - } - case TransactionType.ModifyAsset: { - return algosdk.makeAssetConfigTxnWithSuggestedParams( - fromAccountAddr, - encodeNote(execParams.payFlags.note, execParams.payFlags.noteb64), - execParams.assetID, - execParams.fields.manager !== "" ? execParams.fields.manager : undefined, - execParams.fields.reserve !== "" ? execParams.fields.reserve : undefined, - execParams.fields.freeze !== "" ? execParams.fields.freeze : undefined, - execParams.fields.clawback !== "" ? execParams.fields.clawback : undefined, - suggestedParams, - false - ); - } - case TransactionType.FreezeAsset: { - return algosdk.makeAssetFreezeTxnWithSuggestedParams( - fromAccountAddr, - encodeNote(execParams.payFlags.note, execParams.payFlags.noteb64), - execParams.assetID, - execParams.freezeTarget, - execParams.freezeState, - suggestedParams - ); - } - case TransactionType.RevokeAsset: { - return algosdk.makeAssetTransferTxnWithSuggestedParams( - fromAccountAddr, - execParams.recipient, - execParams.payFlags.closeRemainderTo, - execParams.revocationTarget, - execParams.amount, - encodeNote(execParams.payFlags.note, execParams.payFlags.noteb64), - execParams.assetID, - suggestedParams - ); - } - case TransactionType.DestroyAsset: { - return algosdk.makeAssetDestroyTxnWithSuggestedParams( - fromAccountAddr, - encodeNote(execParams.payFlags.note, execParams.payFlags.noteb64), - execParams.assetID, - suggestedParams - ); - } - case TransactionType.TransferAlgo: { - return algosdk.makePaymentTxnWithSuggestedParams( - fromAccountAddr, - execParams.toAccountAddr, - execParams.amountMicroAlgos, - execParams.payFlags.closeRemainderTo, - note, - suggestedParams, - execParams.payFlags.rekeyTo); - } - case TransactionType.ClearSSC: { - return algosdk.makeApplicationClearStateTxn( - fromAccountAddr, - suggestedParams, - execParams.appID, - parseSSCAppArgs(execParams.appArgs), - execParams.accounts, - execParams.foreignApps, - execParams.foreignAssets, - note, - execParams.lease, - execParams.payFlags.rekeyTo - ); - } - case TransactionType.DeleteSSC: { - return algosdk.makeApplicationDeleteTxn( - fromAccountAddr, - suggestedParams, - execParams.appID, - parseSSCAppArgs(execParams.appArgs), - execParams.accounts, - execParams.foreignApps, - execParams.foreignAssets, - note, - execParams.lease, - execParams.payFlags.rekeyTo - ); - } - case TransactionType.CallNoOpSSC: { - return algosdk.makeApplicationNoOpTxn( - fromAccountAddr, - suggestedParams, - execParams.appID, - parseSSCAppArgs(execParams.appArgs), - execParams.accounts, - execParams.foreignApps, - execParams.foreignAssets, - note, - execParams.lease, - execParams.payFlags.rekeyTo); - } - case TransactionType.CloseSSC: { - return algosdk.makeApplicationCloseOutTxn( - fromAccountAddr, - suggestedParams, - execParams.appID, - parseSSCAppArgs(execParams.appArgs), - execParams.accounts, - execParams.foreignApps, - execParams.foreignAssets, - note, - execParams.lease, - execParams.payFlags.rekeyTo - ); - } - case TransactionType.DeployASA: { - if (execParams.asaDef) { - // https://github.com/algorand/docs/blob/master/examples/assets/v2/javascript/AssetExample.js#L104 - return algosdk.makeAssetCreateTxnWithSuggestedParams( - fromAccountAddr, - note, - BigInt(execParams.asaDef.total ?? 0), - execParams.asaDef.decimals, - execParams.asaDef.defaultFrozen, - execParams.asaDef.manager, - execParams.asaDef.reserve, - execParams.asaDef.freeze, - execParams.asaDef.clawback, - execParams.asaDef.unitName, - execParams.asaName, - execParams.asaDef.url, - execParams.asaDef.metadataHash, - suggestedParams - ); - } else { - throw new RuntimeError( - RUNTIME_ERRORS.ASA.PARAM_PARSE_ERROR, { - reason: "ASA Definition not found", - source: execParams.asaName - }); - } - } - case TransactionType.DeploySSC: { - const onComplete = algosdk.OnApplicationComplete.NoOpOC; - - return algosdk.makeApplicationCreateTxn( - fromAccountAddr, - suggestedParams, - onComplete, - execParams.approvalProg, - execParams.clearProg, - execParams.localInts, - execParams.localBytes, - execParams.globalInts, - execParams.globalBytes, - parseSSCAppArgs(execParams.appArgs), - execParams.accounts, - execParams.foreignApps, - execParams.foreignAssets, - note, - execParams.lease, - execParams.payFlags.rekeyTo - ); - } - case TransactionType.UpdateSSC: { - return algosdk.makeApplicationUpdateTxn( - fromAccountAddr, - suggestedParams, - execParams.appID, - execParams.approvalProg, - execParams.clearProg, - parseSSCAppArgs(execParams.appArgs), - execParams.accounts, - execParams.foreignApps, - execParams.foreignAssets, - note, - execParams.lease, - execParams.payFlags.rekeyTo); - } - case TransactionType.OptInSSC: { - return algosdk.makeApplicationOptInTxn( - fromAccountAddr, - suggestedParams, - execParams.appID, - parseSSCAppArgs(execParams.appArgs), - execParams.accounts, - execParams.foreignApps, - execParams.foreignAssets, - note, - execParams.lease, - execParams.payFlags.rekeyTo); - } - case TransactionType.OptInASA: { - return algosdk.makeAssetTransferTxnWithSuggestedParams( - fromAccountAddr, - fromAccountAddr, - undefined, - undefined, - 0, - note, - execParams.assetID, - suggestedParams - ); - } - default: { - throw new RuntimeError(RUNTIME_ERRORS.TRANSACTION.TRANSACTION_TYPE_ERROR, - { transaction: transactionType }); - } - } -} diff --git a/packages/runtime/src/logicsig.ts b/packages/runtime/src/logicsig.ts index 1d3dffab3..e64e515ef 100644 --- a/packages/runtime/src/logicsig.ts +++ b/packages/runtime/src/logicsig.ts @@ -1,3 +1,4 @@ +import { parsing } from "@algo-builder/web"; import { decodeAddress, encodeAddress, generateAccount, LogicSigBase, MultiSig, multisigAddress, MultisigMetadata, @@ -8,7 +9,7 @@ import * as tweet from "tweetnacl-ts"; import { RUNTIME_ERRORS } from "./errors/errors-list"; import { RuntimeError } from "./errors/runtime-errors"; import { compareArray } from "./lib/compare"; -import { convertToString, stringToBytes } from "./lib/parsing"; +import { convertToString } from "./lib/parsing"; /** * Note: We cannot use algosdk LogicSig class here, @@ -26,7 +27,7 @@ export class LogicSig { constructor (program: string, args: Uint8Array[]) { this.tag = Buffer.from("Program"); - this.logic = stringToBytes(program); + this.logic = parsing.stringToBytes(program); this.args = args; this.sig = new Uint8Array(0); this.msig = undefined; diff --git a/packages/runtime/src/runtime.ts b/packages/runtime/src/runtime.ts index c25c87c19..e3bfc0607 100644 --- a/packages/runtime/src/runtime.ts +++ b/packages/runtime/src/runtime.ts @@ -1,5 +1,6 @@ /* eslint sonarjs/no-duplicate-string: 0 */ /* eslint sonarjs/no-small-switch: 0 */ +import { parsing, tx as webTx, types } from "@algo-builder/web"; import algosdk, { AssetDef, decodeAddress } from "algosdk"; import cloneDeep from "lodash.clonedeep"; @@ -8,14 +9,13 @@ import { Ctx } from "./ctx"; import { RUNTIME_ERRORS } from "./errors/errors-list"; import { RuntimeError } from "./errors/runtime-errors"; import { Interpreter, loadASAFile } from "./index"; -import { convertToString, parseSSCAppArgs } from "./lib/parsing"; -import { encodeNote, getFromAddress, mkTransaction } from "./lib/txn"; +import { convertToString } from "./lib/parsing"; import { LogicSig } from "./logicsig"; import { mockSuggestedParams } from "./mock/tx"; import { - AccountAddress, AccountStoreI, ASADefs, ASADeploymentFlags, ASAInfo, AssetHoldingM, Context, ExecParams, - ExecutionMode, SignType, SSCAttributesM, SSCDeploymentFlags, SSCInfo, SSCOptionalFlags, - StackElem, State, TransactionType, Txn, TxParams + AccountAddress, AccountStoreI, AppDeploymentFlags, AppOptionalFlags, + ASADeploymentFlags, ASAInfo, AssetHoldingM, Context, + ExecutionMode, SSCAttributesM, SSCInfo, StackElem, State, Txn, TxParams } from "./types"; export class Runtime { @@ -28,7 +28,7 @@ export class Runtime { */ private store: State; ctx: Context; - loadedAssetsDefs: ASADefs; + loadedAssetsDefs: types.ASADefs; // https://developer.algorand.org/docs/features/transactions/?query=round private round: number; private timestamp: number; @@ -275,7 +275,7 @@ export class Runtime { * @param txnParams : Transaction parameters for current txn or txn Group * @returns: [current transaction, transaction group] */ - createTxnContext (txnParams: ExecParams | ExecParams[]): [Txn, Txn[]] { + createTxnContext (txnParams: types.ExecParams | types.ExecParams[]): [Txn, Txn[]] { // if txnParams is array, then user is requesting for a group txn if (Array.isArray(txnParams)) { if (txnParams.length > 16) { @@ -285,7 +285,7 @@ export class Runtime { const txns = []; for (const txnParam of txnParams) { // create encoded_obj for each txn in group const mockParams = mockSuggestedParams(txnParam.payFlags, this.round); - const tx = mkTransaction(txnParam, mockParams); + const tx = webTx.mkTransaction(txnParam, mockParams); // convert to encoded obj for compatibility const encodedTxnObj = tx.get_obj_for_encoding() as Txn; encodedTxnObj.txID = tx.txID(); @@ -295,7 +295,7 @@ export class Runtime { } else { // if not array, then create a single transaction const mockParams = mockSuggestedParams(txnParams.payFlags, this.round); - const tx = mkTransaction(txnParams, mockParams); + const tx = webTx.mkTransaction(txnParams, mockParams); const encodedTxnObj = tx.get_obj_for_encoding() as Txn; encodedTxnObj.txID = tx.txID(); @@ -309,7 +309,7 @@ export class Runtime { // this funtion is called only for validation of parameters passed algosdk.makeAssetCreateTxnWithSuggestedParams( flags.creator.addr, - encodeNote(flags.note, flags.noteb64), + webTx.encodeNote(flags.note, flags.noteb64), asaDef.total, asaDef.decimals, asaDef.defaultFrozen, @@ -367,7 +367,7 @@ export class Runtime { } // creates new application transaction object and update context - addCtxAppCreateTxn (flags: SSCDeploymentFlags, payFlags: TxParams): void { + addCtxAppCreateTxn (flags: AppDeploymentFlags, payFlags: TxParams): void { const txn = algosdk.makeApplicationCreateTxn( flags.sender.addr, mockSuggestedParams(payFlags, this.round), @@ -378,7 +378,7 @@ export class Runtime { flags.localBytes, flags.globalInts, flags.globalBytes, - parseSSCAppArgs(flags.appArgs), + parsing.parseAppArgs(flags.appArgs), flags.accounts, flags.foreignApps, flags.foreignAssets, @@ -403,7 +403,7 @@ export class Runtime { * NOTE - approval and clear program must be the TEAL code as string (not compiled code) */ addApp ( - flags: SSCDeploymentFlags, payFlags: TxParams, + flags: AppDeploymentFlags, payFlags: TxParams, approvalProgram: string, clearProgram: string, debugStack?: number ): number { @@ -420,12 +420,12 @@ export class Runtime { senderAddr: string, appID: number, payFlags: TxParams, - flags: SSCOptionalFlags): void { + flags: AppOptionalFlags): void { const txn = algosdk.makeApplicationOptInTxn( senderAddr, mockSuggestedParams(payFlags, this.round), appID, - parseSSCAppArgs(flags.appArgs), + parsing.parseAppArgs(flags.appArgs), flags.accounts, flags.foreignApps, flags.foreignAssets, @@ -449,7 +449,7 @@ export class Runtime { * each opcode execution (upto depth = debugStack) */ optInToApp (accountAddr: string, appID: number, - flags: SSCOptionalFlags, payFlags: TxParams, debugStack?: number): void { + flags: AppOptionalFlags, payFlags: TxParams, debugStack?: number): void { this.addCtxOptInTx(accountAddr, appID, payFlags, flags); this.ctx.debugStack = debugStack; this.ctx.optInToApp(accountAddr, appID); @@ -462,14 +462,14 @@ export class Runtime { senderAddr: string, appID: number, payFlags: TxParams, - flags: SSCOptionalFlags): void { + flags: AppOptionalFlags): void { const txn = algosdk.makeApplicationUpdateTxn( senderAddr, mockSuggestedParams(payFlags, this.round), appID, new Uint8Array(32), // mock approval program new Uint8Array(32), // mock clear progam - parseSSCAppArgs(flags.appArgs), + parsing.parseAppArgs(flags.appArgs), flags.accounts, flags.foreignApps, flags.foreignAssets, @@ -501,7 +501,7 @@ export class Runtime { approvalProgram: string, clearProgram: string, payFlags: TxParams, - flags: SSCOptionalFlags, + flags: AppOptionalFlags, debugStack?: number ): void { this.addCtxAppUpdateTx(senderAddr, appID, payFlags, flags); @@ -544,14 +544,14 @@ export class Runtime { * @param debugStack: if passed then TEAL Stack is logged to console after * each opcode execution (upto depth = debugStack) */ - validateLsigAndRun (txnParam: ExecParams, debugStack?: number): void { + validateLsigAndRun (txnParam: types.ExecParams, debugStack?: number): void { // check if transaction is signed by logic signature, // if yes verify signature and run logic - if (txnParam.sign === SignType.LogicSignature && txnParam.lsig) { + if (txnParam.sign === types.SignType.LogicSignature && txnParam.lsig) { this.ctx.args = txnParam.args ?? txnParam.lsig.args; // signature validation - const fromAccountAddr = getFromAddress(txnParam); + const fromAccountAddr = webTx.getFromAddress(txnParam); const result = txnParam.lsig.verify(decodeAddress(fromAccountAddr).publicKey); if (!result) { throw new RuntimeError(RUNTIME_ERRORS.GENERAL.LOGIC_SIGNATURE_VALIDATION_FAILED, @@ -575,15 +575,15 @@ export class Runtime { * @param debugStack: if passed then TEAL Stack is logged to console after * each opcode execution (upto depth = debugStack) */ - executeTx (txnParams: ExecParams | ExecParams[], debugStack?: number): void { + executeTx (txnParams: types.ExecParams | types.ExecParams[], debugStack?: number): void { const txnParameters = Array.isArray(txnParams) ? txnParams : [txnParams]; for (const txn of txnParameters) { switch (txn.type) { - case TransactionType.DeployASA: { + case types.TransactionType.DeployASA: { txn.asaDef = this.loadedAssetsDefs[txn.asaName]; break; } - case TransactionType.DeploySSC: { + case types.TransactionType.DeployApp: { txn.approvalProg = new Uint8Array(32); // mock approval program txn.clearProg = new Uint8Array(32); // mock clear program break; diff --git a/packages/runtime/src/types.ts b/packages/runtime/src/types.ts index aa0fb2c77..0aabfaa59 100644 --- a/packages/runtime/src/types.ts +++ b/packages/runtime/src/types.ts @@ -1,12 +1,10 @@ +import { types } from "@algo-builder/web"; import { Account as AccountSDK, AssetDef, - LogicSig, - LogicSigArgs, SSCSchemaConfig, TxnEncodedObj } from "algosdk"; -import * as z from 'zod'; import { Add, Addr, Arg, Byte, Bytec, @@ -15,7 +13,6 @@ import { } from "./interpreter/opcode-list"; import { TxnFields } from "./lib/constants"; import type { IStack } from "./lib/stack"; -import type { ASADefSchema, ASADefsSchema } from "./types-input"; export type Operator = Len | Add | Sub | Mul | Div | Arg | Bytecblock | Bytec | Addr | Int | Byte | Pragma; @@ -91,7 +88,7 @@ export interface DeployedAssetInfo { // ASA deployment information (log) export interface ASAInfo extends DeployedAssetInfo { assetIndex: number - assetDef: ASADef + assetDef: types.ASADef } // Stateful smart contract deployment information (log) @@ -110,10 +107,10 @@ export interface Context { getAccount: (address: string) => AccountStoreI getAssetAccount: (assetId: number) => AccountStoreI getApp: (appID: number, line?: number) => SSCAttributesM - transferAlgo: (txnParam: AlgoTransferParam) => void + transferAlgo: (txnParam: types.AlgoTransferParam) => void deductFee: (sender: AccountAddress, index: number) => void - transferAsset: (txnParam: AssetTransferParam) => void - modifyAsset: (assetId: number, fields: AssetModFields) => void + transferAsset: (txnParam: types.AssetTransferParam) => void + modifyAsset: (assetId: number, fields: types.AssetModFields) => void freezeAsset: (assetId: number, freezeTarget: string, freezeState: boolean) => void revokeAsset: ( recipient: string, assetID: number, @@ -122,11 +119,11 @@ export interface Context { destroyAsset: (assetId: number) => void deleteApp: (appID: number) => void closeApp: (sender: AccountAddress, appID: number) => void - processTransactions: (txnParams: ExecParams[]) => void + processTransactions: (txnParams: types.ExecParams[]) => void addAsset: (name: string, fromAccountAddr: AccountAddress, flags: ASADeploymentFlags) => number optIntoASA: (assetIndex: number, address: AccountAddress, flags: TxParams) => void addApp: ( - fromAccountAddr: string, flags: SSCDeploymentFlags, + fromAccountAddr: string, flags: AppDeploymentFlags, approvalProgram: string, clearProgram: string ) => number optInToApp: (accountAddr: string, appID: number) => void @@ -180,12 +177,12 @@ export interface AccountStoreI { balance: () => bigint getApp: (appID: number) => SSCAttributesM | undefined getAppFromLocal: (appID: number) => AppLocalStateM | undefined - addApp: (appID: number, params: SSCDeploymentFlags, + addApp: (appID: number, params: AppDeploymentFlags, approvalProgram: string, clearProgram: string) => CreatedAppM getAssetDef: (assetId: number) => AssetDef | undefined getAssetHolding: (assetId: number) => AssetHoldingM | undefined - addAsset: (assetId: number, name: string, asadef: ASADef) => AssetDef - modifyAsset: (assetId: number, fields: AssetModFields) => void + addAsset: (assetId: number, name: string, asadef: types.ASADef) => AssetDef + modifyAsset: (assetId: number, fields: types.AssetModFields) => void closeAsset: (assetId: number) => void setFreezeState: (assetId: number, state: boolean) => void destroyAsset: (assetId: number) => void @@ -248,7 +245,7 @@ export interface TxParams { /** * Stateful Smart contract flags for specifying sender and schema */ -export interface SSCDeploymentFlags extends SSCOptionalFlags { +export interface AppDeploymentFlags extends AppOptionalFlags { sender: AccountSDK localInts: number localBytes: number @@ -258,7 +255,7 @@ export interface SSCDeploymentFlags extends SSCOptionalFlags { /** * Stateful smart contract transaction optional parameters (accounts, args..). */ -export interface SSCOptionalFlags { +export interface AppOptionalFlags { /** * Transaction specific arguments accessed from * the application's approval-program and clear-state-program. @@ -288,145 +285,6 @@ export interface SSCOptionalFlags { // you can learn more about these parameters from here.(https://developer.algorand.org/docs/reference/transactions/#application-call-transaction) } -/** - * Transaction execution parameters (on blockchain OR runtime) */ -export type ExecParams = AlgoTransferParam | AssetTransferParam | SSCCallsParam | -ModifyAssetParam | FreezeAssetParam | RevokeAssetParam | -DestroyAssetParam | DeployASAParam | DeploySSCParam | -OptInSSCParam | OptInASAParam | UpdateSSCParam; - -export enum SignType { - SecretKey, - LogicSignature -} - -export enum TransactionType { - TransferAlgo, - TransferAsset, - ModifyAsset, - FreezeAsset, - RevokeAsset, - DestroyAsset, - CallNoOpSSC, - ClearSSC, - CloseSSC, - DeleteSSC, - DeployASA, - DeploySSC, - OptInASA, - OptInSSC, - UpdateSSC -} - -interface SignWithSk { - sign: SignType.SecretKey - fromAccount: AccountSDK - /** - * if passed then it will be used as the from account address, but tx will be signed - * by fromAcount's sk. This is used if an account address is rekeyed to another account. */ - fromAccountAddr?: AccountAddress -} - -interface SignWithLsig { - sign: SignType.LogicSignature - fromAccountAddr: AccountAddress - lsig: LogicSig - /** stateless smart contract args */ - args?: LogicSigArgs -} - -export type Sign = SignWithSk | SignWithLsig; - -export type BasicParams = Sign & { - payFlags: TxParams -}; - -export type DeployASAParam = BasicParams & { - type: TransactionType.DeployASA - asaName: string - asaDef?: Partial -}; - -export type DeploySSCParam = BasicParams & SSCOptionalFlags & { - type: TransactionType.DeploySSC - approvalProgram: string - clearProgram: string - localInts: number - localBytes: number - globalInts: number - globalBytes: number - approvalProg?: Uint8Array - clearProg?: Uint8Array -}; - -export type UpdateSSCParam = BasicParams & SSCOptionalFlags & { - type: TransactionType.UpdateSSC - appID: number - newApprovalProgram: string - newClearProgram: string - approvalProg?: Uint8Array - clearProg?: Uint8Array -}; - -export type OptInSSCParam = BasicParams & SSCOptionalFlags & { - type: TransactionType.OptInSSC - appID: number -}; - -export type OptInASAParam = BasicParams & { - type: TransactionType.OptInASA - assetID: number | string -}; - -export type ModifyAssetParam = BasicParams & { - type: TransactionType.ModifyAsset - assetID: number | string - fields: AssetModFields -}; - -export type FreezeAssetParam = BasicParams & { - type: TransactionType.FreezeAsset - assetID: number | string - freezeTarget: AccountAddress - freezeState: boolean -}; - -export type RevokeAssetParam = BasicParams & { - type: TransactionType.RevokeAsset - /** - * Revoked assets are sent to this address - */ - recipient: AccountAddress - assetID: number | string - /** Revocation target is the account from which the clawback revokes asset. */ - revocationTarget: AccountAddress - amount: number | bigint -}; - -export type DestroyAssetParam = BasicParams & { - type: TransactionType.DestroyAsset - assetID: number | string -}; - -export type AlgoTransferParam = BasicParams & { - type: TransactionType.TransferAlgo - toAccountAddr: AccountAddress - amountMicroAlgos: number | bigint -}; - -export type AssetTransferParam = BasicParams & { - type: TransactionType.TransferAsset - toAccountAddr: AccountAddress - amount: number | bigint - assetID: number | string -}; - -export type SSCCallsParam = BasicParams & SSCOptionalFlags & { - type: TransactionType.CallNoOpSSC | TransactionType.ClearSSC | - TransactionType.CloseSSC | TransactionType.DeleteSSC - appID: number -}; - export interface AnyMap { [key: string]: any // eslint-disable-line @typescript-eslint/no-explicit-any } @@ -445,22 +303,6 @@ export interface ASADeploymentFlags extends TxParams { * SDK account type, used in algob */ export type AccountMap = Map; -export type ASADef = z.infer; - -export type ASADefs = z.infer; - -/** - * After an asset has been created only the manager, - * reserve, freeze and reserve accounts can be changed. - * All other parameters are locked for the life of the asset. - */ -export interface AssetModFields { - manager?: string - reserve?: string - freeze?: string - clawback?: string -} - /** * SDK decoding types (Configure how the integer will be decoded) * https://github.com/algorand/js-algorand-sdk/blob/develop/src/encoding/uint64.ts#L29 diff --git a/packages/runtime/test/integration/app-update.ts b/packages/runtime/test/integration/app-update.ts index da2bf53b2..e3d9d522d 100644 --- a/packages/runtime/test/integration/app-update.ts +++ b/packages/runtime/test/integration/app-update.ts @@ -1,9 +1,9 @@ +import { types } from "@algo-builder/web"; import { assert } from "chai"; import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; import { AccountStore, Runtime } from "../../src/index"; import { ALGORAND_ACCOUNT_MIN_BALANCE } from "../../src/lib/constants"; -import { SignType, TransactionType, UpdateSSCParam } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; import { expectRuntimeError } from "../helpers/runtime-errors"; @@ -18,7 +18,7 @@ describe("App Update Test", function () { let approvalProgram: string; let clearProgram: string; let appID: number; - let groupTx: UpdateSSCParam[]; + let groupTx: types.UpdateAppParam[]; this.beforeEach(async function () { runtime = new Runtime([john, alice]); // setup test @@ -36,8 +36,8 @@ describe("App Update Test", function () { groupTx = [ { - type: TransactionType.UpdateSSC, - sign: SignType.SecretKey, + type: types.TransactionType.UpdateApp, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: appID, newApprovalProgram: approvalProgram, @@ -46,8 +46,8 @@ describe("App Update Test", function () { appArgs: ['int:2'] }, { - type: TransactionType.UpdateSSC, - sign: SignType.SecretKey, + type: types.TransactionType.UpdateApp, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: appID, newApprovalProgram: approvalProgram, diff --git a/packages/runtime/test/integration/atomic-transfer.ts b/packages/runtime/test/integration/atomic-transfer.ts index 60abc4288..e9f842c41 100644 --- a/packages/runtime/test/integration/atomic-transfer.ts +++ b/packages/runtime/test/integration/atomic-transfer.ts @@ -1,8 +1,8 @@ +import { types } from "@algo-builder/web"; import { assert } from "chai"; -import { RUNTIME_ERRORS } from "../../build/errors/errors-list"; +import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; import { AccountStore, Runtime } from "../../src/index"; -import { ExecParams, SignType, TransactionType } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; import { expectRuntimeError } from "../helpers/runtime-errors"; @@ -52,18 +52,18 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { const key = "counter"; it("should execute group of (payment + asset transaction) successfully", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.address, amountMicroAlgos: 100, payFlags: { totalFee: 1000 } }, { - type: TransactionType.TransferAsset, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAsset, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.address, amount: 10, @@ -86,18 +86,18 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { }); it("should not execute payment transaction (in group) if asset transaction fails", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.address, amountMicroAlgos: 100, payFlags: { totalFee: 1000 } }, { - type: TransactionType.TransferAsset, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAsset, + sign: types.SignType.SecretKey, fromAccount: alice.account, toAccountAddr: john.address, amount: 1000, @@ -124,17 +124,17 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { }); it("should execute payment and ssc call", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.CallNoOpSSC, - sign: SignType.SecretKey, + type: types.TransactionType.CallNoOpSSC, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: appID, payFlags: { totalFee: 1000 } }, { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.address, amountMicroAlgos: 100, @@ -157,17 +157,17 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { }); it("should fail if payment transaction in group fails", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.CallNoOpSSC, - sign: SignType.SecretKey, + type: types.TransactionType.CallNoOpSSC, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: appID, payFlags: { totalFee: 1000 } }, { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: alice.account, toAccountAddr: john.address, amountMicroAlgos: 6e6, @@ -191,10 +191,10 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { }); it("should not freeze asset if payment fails", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.FreezeAsset, - sign: SignType.SecretKey, + type: types.TransactionType.FreezeAsset, + sign: types.SignType.SecretKey, fromAccount: john.account, assetID: assetId, freezeTarget: alice.address, @@ -202,8 +202,8 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { payFlags: {} }, { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: alice.account, toAccountAddr: john.address, amountMicroAlgos: 6e6, @@ -227,18 +227,18 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { clawback: john.address, freeze: john.address }; - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.ModifyAsset, - sign: SignType.SecretKey, + type: types.TransactionType.ModifyAsset, + sign: types.SignType.SecretKey, fromAccount: john.account, assetID: assetId, fields: modFields, payFlags: {} }, { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: alice.account, toAccountAddr: john.address, amountMicroAlgos: 6e6, @@ -259,18 +259,18 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { it("should not revoke asset if payment fails", () => { // transfer asset to alice runtime.executeTx({ - type: TransactionType.TransferAsset, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAsset, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.account.addr, amount: 20, assetID: assetId, payFlags: { totalFee: 1000 } }); - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.RevokeAsset, - sign: SignType.SecretKey, + type: types.TransactionType.RevokeAsset, + sign: types.SignType.SecretKey, fromAccount: john.account, recipient: john.address, assetID: assetId, @@ -279,8 +279,8 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { payFlags: {} }, { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: alice.account, toAccountAddr: john.address, amountMicroAlgos: 6e6, @@ -300,17 +300,17 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { }); it("should not destroy asset if payment fails", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.DestroyAsset, - sign: SignType.SecretKey, + type: types.TransactionType.DestroyAsset, + sign: types.SignType.SecretKey, fromAccount: john.account, assetID: assetId, payFlags: {} }, { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: alice.account, toAccountAddr: john.address, amountMicroAlgos: 6e6, @@ -328,17 +328,17 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { }); it("should fail close app if payment transaction fails", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.CloseSSC, - sign: SignType.SecretKey, + type: types.TransactionType.CloseApp, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: appID, payFlags: { totalFee: 1000 } }, { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: alice.account, toAccountAddr: john.address, amountMicroAlgos: 6e6, @@ -356,17 +356,17 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { }); it("should fail clear app if payment transaction fails", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.ClearSSC, - sign: SignType.SecretKey, + type: types.TransactionType.ClearApp, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: appID, payFlags: { totalFee: 1000 } }, { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: alice.account, toAccountAddr: john.address, amountMicroAlgos: 6e6, @@ -386,32 +386,32 @@ describe("Algorand Smart Contracts - Atomic Transfers", function () { it("should fail asset payment, and algo payment if ssc call fails", () => { // close out from app runtime.executeTx({ - type: TransactionType.ClearSSC, - sign: SignType.SecretKey, + type: types.TransactionType.ClearApp, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: appID, payFlags: { totalFee: 1000 } }); syncAccounts(); - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.ClearSSC, - sign: SignType.SecretKey, + type: types.TransactionType.ClearApp, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: appID, payFlags: { totalFee: 1000 } }, { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: alice.account, toAccountAddr: john.address, amountMicroAlgos: 100, payFlags: { totalFee: 1000 } }, { - type: TransactionType.TransferAsset, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAsset, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.account.addr, amount: 10, diff --git a/packages/runtime/test/integration/basic-teal.ts b/packages/runtime/test/integration/basic-teal.ts index dcb4428be..478d5e52e 100644 --- a/packages/runtime/test/integration/basic-teal.ts +++ b/packages/runtime/test/integration/basic-teal.ts @@ -1,10 +1,10 @@ +import { types } from "@algo-builder/web"; import { assert } from "chai"; import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; import { AccountStore, Runtime } from "../../src/index"; import { ALGORAND_ACCOUNT_MIN_BALANCE } from "../../src/lib/constants"; import { LogicSig } from "../../src/logicsig"; -import { AlgoTransferParam, SignType, TransactionType } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; import { expectRuntimeError } from "../helpers/runtime-errors"; @@ -19,7 +19,7 @@ describe("Stateless Algorand Smart Contracts delegated signature mode", function let john: AccountStore; let bob: AccountStore; let runtime: Runtime; - let txnParams: AlgoTransferParam; + let txnParams: types.AlgoTransferParam; this.beforeAll(async function () { john = new AccountStore(initialJohnHolding); @@ -27,8 +27,8 @@ describe("Stateless Algorand Smart Contracts delegated signature mode", function runtime = new Runtime([john, bob]); txnParams = { - type: TransactionType.TransferAlgo, // payment - sign: SignType.LogicSignature, + type: types.TransactionType.TransferAlgo, // payment + sign: types.SignType.LogicSignature, fromAccountAddr: john.account.addr, toAccountAddr: bob.address, amountMicroAlgos: 100n, @@ -54,7 +54,7 @@ describe("Stateless Algorand Smart Contracts delegated signature mode", function runtime.executeTx({ ...txnParams, - sign: SignType.LogicSignature, + sign: types.SignType.LogicSignature, fromAccountAddr: john.address, lsig: lsig }); diff --git a/packages/runtime/test/integration/close-clear-ssc.ts b/packages/runtime/test/integration/close-clear-ssc.ts index 5708ea2ab..3e32301a0 100644 --- a/packages/runtime/test/integration/close-clear-ssc.ts +++ b/packages/runtime/test/integration/close-clear-ssc.ts @@ -1,10 +1,9 @@ +import { parsing, types } from "@algo-builder/web"; import { assert } from "chai"; import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; import { AccountStore, Runtime } from "../../src/index"; import { ALGORAND_ACCOUNT_MIN_BALANCE, APPLICATION_BASE_FEE } from "../../src/lib/constants"; -import { stringToBytes } from "../../src/lib/parsing"; -import { SignType, SSCCallsParam, TransactionType } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; import { expectRuntimeError } from "../helpers/runtime-errors"; @@ -18,7 +17,7 @@ describe("ASC - CloseOut from Application and Clear State", function () { let runtime: Runtime; let approvalProgram: string; let clearProgram: string; - let closeOutParams: SSCCallsParam; + let closeOutParams: types.AppCallsParam; const flags = { sender: john.account, globalBytes: 2, @@ -32,8 +31,8 @@ describe("ASC - CloseOut from Application and Clear State", function () { clearProgram = getProgram('clear.teal'); closeOutParams = { - type: TransactionType.CloseSSC, - sign: SignType.SecretKey, + type: types.TransactionType.CloseApp, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: 11, payFlags: { totalFee: 1000 } @@ -79,7 +78,7 @@ describe("ASC - CloseOut from Application and Clear State", function () { // since app is not deleted from global, global state should be updated by smart contract const globalVal = runtime.getGlobalState(appID, 'global-key'); - assert.deepEqual(globalVal, stringToBytes('global-val')); + assert.deepEqual(globalVal, parsing.stringToBytes('global-val')); // minimum balance should decrease to initial balance after closing out assert.equal(john.minBalance, initialJohnMinBalance); @@ -107,9 +106,9 @@ describe("ASC - CloseOut from Application and Clear State", function () { initialJohnMinBalance + (APPLICATION_BASE_FEE + ((25000 + 3500) * 3 + (25000 + 25000) * 3)) // optInToApp increase ); // verify minimum balance raised after optIn - const invalidParams: SSCCallsParam = { - type: TransactionType.CloseSSC, - sign: SignType.SecretKey, + const invalidParams: types.AppCallsParam = { + type: types.TransactionType.CloseApp, + sign: types.SignType.SecretKey, fromAccount: alice.account, // sending txn sender other than creator (john), so txn should be rejected appID: appID, payFlags: {} @@ -135,9 +134,9 @@ describe("ASC - CloseOut from Application and Clear State", function () { const rejectClearProgram = getProgram('rejectClear.teal'); const appID = runtime.addApp(flags, {}, approvalProgram, rejectClearProgram); const initialJohnMinBalance = runtime.getAccount(john.address).minBalance; - const clearAppParams: SSCCallsParam = { - type: TransactionType.ClearSSC, - sign: SignType.SecretKey, + const clearAppParams: types.AppCallsParam = { + type: types.TransactionType.ClearApp, + sign: types.SignType.SecretKey, fromAccount: alice.account, // sending txn sender other than creator (john), so txn should be rejected appID: appID, payFlags: {} diff --git a/packages/runtime/test/integration/crowdfunding.ts b/packages/runtime/test/integration/crowdfunding.ts index c118ae2c4..1e4b6f071 100644 --- a/packages/runtime/test/integration/crowdfunding.ts +++ b/packages/runtime/test/integration/crowdfunding.ts @@ -1,9 +1,9 @@ +import { parsing } from "@algo-builder/web"; import { assert } from "chai"; import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; import { AccountStore, Runtime } from "../../src/index"; -import { addressToPk, uint64ToBigEndian } from "../../src/lib/parsing"; -import { SSCDeploymentFlags, StackElem } from "../../src/types"; +import { AppDeploymentFlags, StackElem } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; import { expectRuntimeError } from "../helpers/runtime-errors"; @@ -15,7 +15,7 @@ describe("Crowdfunding basic tests", function () { let runtime: Runtime; let approvalProgram: string; let clearProgram: string; - let flags: SSCDeploymentFlags; + let flags: AppDeploymentFlags; this.beforeAll(async function () { runtime = new Runtime([john]); // setup test approvalProgram = getProgram('crowdfunding.teal'); @@ -39,7 +39,7 @@ describe("Crowdfunding basic tests", function () { }); it("should create application and update global state if correct args are passed", function () { - const validFlags: SSCDeploymentFlags = Object.assign({}, flags); + const validFlags: AppDeploymentFlags = Object.assign({}, flags); // Get begin date to pass in const beginDate = new Date(); @@ -54,11 +54,11 @@ describe("Crowdfunding basic tests", function () { fundCloseDate.setSeconds(fundCloseDate.getSeconds() + 120000); const appArgs = [ - uint64ToBigEndian(beginDate.getTime()), - uint64ToBigEndian(endDate.getTime()), - uint64ToBigEndian(7000000), - addressToPk(john.address), - uint64ToBigEndian(fundCloseDate.getTime()) + parsing.uint64ToBigEndian(beginDate.getTime()), + parsing.uint64ToBigEndian(endDate.getTime()), + parsing.uint64ToBigEndian(7000000), + parsing.addressToPk(john.address), + parsing.uint64ToBigEndian(fundCloseDate.getTime()) ]; const johnMinBalance = john.minBalance; @@ -69,7 +69,7 @@ describe("Crowdfunding basic tests", function () { const getGlobal = (key: string): StackElem |undefined => runtime.getGlobalState(appID, key); - const johnPk = addressToPk(john.address); + const johnPk = parsing.addressToPk(john.address); // verify global state assert.isDefined(appID); diff --git a/packages/runtime/test/integration/deleteApp.ts b/packages/runtime/test/integration/deleteApp.ts index 2a7d244ed..9a7435fd0 100644 --- a/packages/runtime/test/integration/deleteApp.ts +++ b/packages/runtime/test/integration/deleteApp.ts @@ -1,9 +1,9 @@ +import { types } from "@algo-builder/web"; import { assert } from "chai"; import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; import { AccountStore, Runtime } from "../../src/index"; import { ALGORAND_ACCOUNT_MIN_BALANCE, APPLICATION_BASE_FEE } from "../../src/lib/constants"; -import { SignType, SSCCallsParam, TransactionType } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; import { expectRuntimeError } from "../helpers/runtime-errors"; @@ -17,7 +17,7 @@ describe("Algorand Smart Contracts - Delete Application", function () { let runtime: Runtime; let approvalProgram: string; let clearProgram: string; - let deleteParams: SSCCallsParam; + let deleteParams: types.AppCallsParam; const flags = { sender: john.account, globalBytes: 2, @@ -31,8 +31,8 @@ describe("Algorand Smart Contracts - Delete Application", function () { clearProgram = getProgram('clear.teal'); deleteParams = { - type: TransactionType.DeleteSSC, - sign: SignType.SecretKey, + type: types.TransactionType.DeleteApp, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: 10, payFlags: { totalFee: 1000 }, @@ -74,9 +74,9 @@ describe("Algorand Smart Contracts - Delete Application", function () { (APPLICATION_BASE_FEE + ((25000 + 3500) * 2 + (25000 + 25000) * 2)) // min balance should increase ); - const deleteParams: SSCCallsParam = { - type: TransactionType.DeleteSSC, - sign: SignType.SecretKey, + const deleteParams: types.AppCallsParam = { + type: types.TransactionType.DeleteApp, + sign: types.SignType.SecretKey, fromAccount: alice.account, appID: appID, payFlags: { totalFee: 1000 }, diff --git a/packages/runtime/test/integration/escrow-account.ts b/packages/runtime/test/integration/escrow-account.ts index 0f80b4877..c31a75490 100644 --- a/packages/runtime/test/integration/escrow-account.ts +++ b/packages/runtime/test/integration/escrow-account.ts @@ -1,11 +1,11 @@ /* eslint sonarjs/no-duplicate-string: 0 */ +import { types } from "@algo-builder/web"; import { assert } from "chai"; import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; import { AccountStore, Runtime } from "../../src/index"; import { ALGORAND_ACCOUNT_MIN_BALANCE } from "../../src/lib/constants"; import { LogicSig } from "../../src/logicsig"; -import { AlgoTransferParam, ExecParams, SignType, TransactionType } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; import { expectRuntimeError } from "../helpers/runtime-errors"; @@ -32,15 +32,15 @@ describe("Logic Signature: Escrow Account", function () { // initialization of lsig and escrow to beforeAll let lsig: LogicSig; let escrow: AccountStore; - let paymentTxParams: AlgoTransferParam; + let paymentTxParams: types.AlgoTransferParam; this.beforeAll(function () { runtime = new Runtime([john, admin]); // setup runtime lsig = runtime.getLogicSig(getProgram('escrow.teal'), []); escrow = runtime.getAccount(lsig.address()); paymentTxParams = { - type: TransactionType.TransferAlgo, - sign: SignType.LogicSignature, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.LogicSignature, lsig: lsig, fromAccountAddr: escrow.address, toAccountAddr: john.address, @@ -57,8 +57,8 @@ describe("Logic Signature: Escrow Account", function () { it("should fund escrow account", function () { runtime.executeTx({ - type: TransactionType.TransferAlgo, // payment - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, // payment + sign: types.SignType.SecretKey, fromAccount: admin.account, toAccountAddr: escrow.address, amountMicroAlgos: initialEscrowHolding, @@ -98,7 +98,7 @@ describe("Logic Signature: Escrow Account", function () { expectRuntimeError( () => runtime.executeTx({ ...paymentTxParams, - type: TransactionType.TransferAsset, + type: types.TransactionType.TransferAsset, assetID: 1111, amount: 10n // asset amount }), @@ -120,7 +120,7 @@ describe("Logic Signature: Escrow Account", function () { const johnBal = john.balance(); assert.isAbove(Number(escrowBal), 0); // escrow balance should be > 0 - const closeParams: ExecParams = { + const closeParams: types.ExecParams = { ...paymentTxParams, amountMicroAlgos: 0n, payFlags: { diff --git a/packages/runtime/test/integration/execute-transaction.ts b/packages/runtime/test/integration/execute-transaction.ts index 29b40a09b..17a4ae01c 100644 --- a/packages/runtime/test/integration/execute-transaction.ts +++ b/packages/runtime/test/integration/execute-transaction.ts @@ -1,8 +1,8 @@ +import { types } from "@algo-builder/web"; import { assert } from "chai"; -import { RUNTIME_ERRORS } from "../../build/errors/errors-list"; +import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; import { AccountStore, Runtime } from "../../src/index"; -import { ExecParams, SignType, TransactionType } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; import { expectRuntimeError } from "../helpers/runtime-errors"; @@ -49,18 +49,18 @@ describe("Algorand Smart Contracts - Execute transaction", function () { } it("should execute group of (payment + asset creation) successfully", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.address, amountMicroAlgos: 100, payFlags: { totalFee: 1000 } }, { - type: TransactionType.DeployASA, - sign: SignType.SecretKey, + type: types.TransactionType.DeployASA, + sign: types.SignType.SecretKey, fromAccount: john.account, asaName: 'gold', payFlags: { totalFee: 1000 } @@ -74,18 +74,18 @@ describe("Algorand Smart Contracts - Execute transaction", function () { }); it("should fail execution group (payment + asset creation), if asset def is not found", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.address, amountMicroAlgos: 100, payFlags: { totalFee: 1000 } }, { - type: TransactionType.DeployASA, - sign: SignType.SecretKey, + type: types.TransactionType.DeployASA, + sign: types.SignType.SecretKey, fromAccount: john.account, asaName: 'doge', payFlags: { totalFee: 1000 } @@ -93,10 +93,7 @@ describe("Algorand Smart Contracts - Execute transaction", function () { ]; const initialJohnAssets = john.getAssetHolding(assetId)?.amount as bigint; assert.isUndefined(initialJohnAssets); - expectRuntimeError( - () => runtime.executeTx(txGroup), - RUNTIME_ERRORS.ASA.PARAM_PARSE_ERROR - ); + assert.throws(() => { runtime.executeTx(txGroup); }, "ABLDR17"); // should not update algo balance syncAccounts(); @@ -109,10 +106,10 @@ describe("Algorand Smart Contracts - Execute transaction", function () { syncAccounts(); const assetInfo = runtime.getAssetInfoFromName('gold'); assert.isDefined(assetInfo); - const tx: ExecParams[] = [ + const tx: types.ExecParams[] = [ { - type: TransactionType.OptInASA, - sign: SignType.SecretKey, + type: types.TransactionType.OptInASA, + sign: types.SignType.SecretKey, fromAccount: alice.account, assetID: assetInfo?.assetIndex as number, payFlags: { totalFee: 1000 } @@ -123,18 +120,18 @@ describe("Algorand Smart Contracts - Execute transaction", function () { }); it("should execute group of (payment + app creation) successfully", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.address, amountMicroAlgos: 100, payFlags: { totalFee: 1000 } }, { - type: TransactionType.DeploySSC, - sign: SignType.SecretKey, + type: types.TransactionType.DeployApp, + sign: types.SignType.SecretKey, fromAccount: john.account, approvalProgram: approvalProgram, clearProgram: clearProgram, @@ -153,18 +150,18 @@ describe("Algorand Smart Contracts - Execute transaction", function () { }); it("should fail execution group (payment + asset creation), if not enough balance", () => { - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.TransferAlgo, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.address, amountMicroAlgos: 1e9, payFlags: { totalFee: 1000 } }, { - type: TransactionType.DeploySSC, - sign: SignType.SecretKey, + type: types.TransactionType.DeployApp, + sign: types.SignType.SecretKey, fromAccount: john.account, approvalProgram: approvalProgram, clearProgram: clearProgram, @@ -191,10 +188,10 @@ describe("Algorand Smart Contracts - Execute transaction", function () { syncAccounts(); const appInfo = runtime.getAppInfoFromName(approvalProgram, clearProgram); assert.isDefined(appInfo); - const tx: ExecParams[] = [ + const tx: types.ExecParams[] = [ { - type: TransactionType.OptInSSC, - sign: SignType.SecretKey, + type: types.TransactionType.OptInToApp, + sign: types.SignType.SecretKey, fromAccount: alice.account, appID: appInfo?.appID as number, payFlags: { totalFee: 1000 } diff --git a/packages/runtime/test/integration/group-index.ts b/packages/runtime/test/integration/group-index.ts index f54e13286..5f7d6aead 100644 --- a/packages/runtime/test/integration/group-index.ts +++ b/packages/runtime/test/integration/group-index.ts @@ -1,6 +1,7 @@ -import { RUNTIME_ERRORS } from '../../build/errors/errors-list'; +import { types } from "@algo-builder/web"; + +import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; import { AccountStore, Runtime } from '../../src/index'; -import { ExecParams, SignType, TransactionType } from '../../src/types'; import { getProgram } from "../helpers/files"; import { useFixture } from '../helpers/integration'; import { expectRuntimeError } from '../helpers/runtime-errors'; @@ -47,17 +48,17 @@ describe('Current Transaction Tests', function () { it('Group Index Check', () => { setupApps(); - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.CallNoOpSSC, - sign: SignType.SecretKey, + type: types.TransactionType.CallNoOpSSC, + sign: types.SignType.SecretKey, fromAccount: creator.account, appID: applicationId1, payFlags: { totalFee: 1000 } }, { - type: TransactionType.CallNoOpSSC, - sign: SignType.SecretKey, + type: types.TransactionType.CallNoOpSSC, + sign: types.SignType.SecretKey, fromAccount: creator.account, appID: applicationId2, payFlags: { totalFee: 1000 } @@ -70,17 +71,17 @@ describe('Current Transaction Tests', function () { it('Failure test for group index', () => { setupApps(); - const txGroup: ExecParams[] = [ + const txGroup: types.ExecParams[] = [ { - type: TransactionType.CallNoOpSSC, - sign: SignType.SecretKey, + type: types.TransactionType.CallNoOpSSC, + sign: types.SignType.SecretKey, fromAccount: creator.account, appID: applicationId2, payFlags: { totalFee: 1000 } }, { - type: TransactionType.CallNoOpSSC, - sign: SignType.SecretKey, + type: types.TransactionType.CallNoOpSSC, + sign: types.SignType.SecretKey, fromAccount: creator.account, appID: applicationId1, payFlags: { totalFee: 1000 } diff --git a/packages/runtime/test/integration/stateful-counter.ts b/packages/runtime/test/integration/stateful-counter.ts index fb06c4807..905178e9e 100644 --- a/packages/runtime/test/integration/stateful-counter.ts +++ b/packages/runtime/test/integration/stateful-counter.ts @@ -1,8 +1,8 @@ +import { types } from "@algo-builder/web"; import { assert } from "chai"; import { AccountStore, Runtime } from "../../src/index"; import { ALGORAND_ACCOUNT_MIN_BALANCE } from "../../src/lib/constants"; -import { ExecParams, SignType, TransactionType } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; @@ -12,9 +12,9 @@ describe("Algorand Smart Contracts - Stateful Counter example", function () { const minBalance = ALGORAND_ACCOUNT_MIN_BALANCE * 10 + fee; const john = new AccountStore(minBalance + fee); - const txnParams: ExecParams = { - type: TransactionType.CallNoOpSSC, - sign: SignType.SecretKey, + const txnParams: types.ExecParams = { + type: types.TransactionType.CallNoOpSSC, + sign: types.SignType.SecretKey, fromAccount: john.account, appID: 0, payFlags: { totalFee: fee } diff --git a/packages/runtime/test/integration/updateApp.ts b/packages/runtime/test/integration/updateApp.ts index 5a625c25b..194f2c109 100644 --- a/packages/runtime/test/integration/updateApp.ts +++ b/packages/runtime/test/integration/updateApp.ts @@ -1,9 +1,9 @@ +import { parsing, types } from "@algo-builder/web"; import { assert } from "chai"; import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; -import { AccountStore, Runtime, stringToBytes } from "../../src/index"; +import { AccountStore, Runtime } from "../../src/index"; import { ALGORAND_ACCOUNT_MIN_BALANCE } from "../../src/lib/constants"; -import { SignType, SSCCallsParam, TransactionType } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; import { expectRuntimeError } from "../helpers/runtime-errors"; @@ -56,14 +56,14 @@ describe("Algorand Smart Contracts - Update Application", function () { // check if program & state is updated after tx execution assert.deepEqual(app[approvalStr], newApprovalProgram); - assert.deepEqual(runtime.getGlobalState(appID, "global-key"), stringToBytes("global-val")); - assert.deepEqual(runtime.getLocalState(appID, creator.address, "local-key"), stringToBytes("local-val")); + assert.deepEqual(runtime.getGlobalState(appID, "global-key"), parsing.stringToBytes("global-val")); + assert.deepEqual(runtime.getLocalState(appID, creator.address, "local-key"), parsing.stringToBytes("local-val")); // now call the smart contract after updating approval program which checks for // global-key and local-key in state (which was set during the update from oldApprovalProgram) - const noOpParams: SSCCallsParam = { - type: TransactionType.CallNoOpSSC, - sign: SignType.SecretKey, + const noOpParams: types.AppCallsParam = { + type: types.TransactionType.CallNoOpSSC, + sign: types.SignType.SecretKey, fromAccount: creator.account, appID: appID, payFlags: { totalFee: 1000 } @@ -72,8 +72,8 @@ describe("Algorand Smart Contracts - Update Application", function () { creator = runtime.getAccount(creator.address); // check state set by the 'new' approval program - assert.deepEqual(runtime.getGlobalState(appID, "new-global-key"), stringToBytes("new-global-val")); - assert.deepEqual(runtime.getLocalState(appID, creator.address, "new-local-key"), stringToBytes("new-local-val")); + assert.deepEqual(runtime.getGlobalState(appID, "new-global-key"), parsing.stringToBytes("new-global-val")); + assert.deepEqual(runtime.getLocalState(appID, creator.address, "new-local-key"), parsing.stringToBytes("new-local-val")); }); it("should not update application if logic is rejected", function () { diff --git a/packages/runtime/test/mocks/stateful.ts b/packages/runtime/test/mocks/stateful.ts index dabd8cc42..068bea901 100644 --- a/packages/runtime/test/mocks/stateful.ts +++ b/packages/runtime/test/mocks/stateful.ts @@ -1,10 +1,10 @@ +import { parsing } from "@algo-builder/web"; import { AssetDef } from "algosdk"; -import { stringToBytes } from "../../src/lib/parsing"; import { AppLocalStateM, AssetHoldingM, SSCAttributesM, StackElem } from "../../src/types"; import { elonAddr } from "./txn"; -const convertToKey = (str: string): string => { return stringToBytes(str).toString(); }; +const convertToKey = (str: string): string => { return parsing.stringToBytes(str).toString(); }; const appLocalState = new Map(); const createdApps = new Map(); @@ -15,11 +15,11 @@ assets.set(3, { 'asset-id': 3, amount: 2n, creator: "string", 'is-frozen': false assets.set(32, { 'asset-id': 32, amount: 2n, creator: "AS", 'is-frozen': false }); const globalStateMap = new Map(); -globalStateMap.set(convertToKey('Hello'), stringToBytes('World')); -globalStateMap.set(convertToKey('global-key'), stringToBytes('global-val')); +globalStateMap.set(convertToKey('Hello'), parsing.stringToBytes('World')); +globalStateMap.set(convertToKey('global-key'), parsing.stringToBytes('global-val')); const localStateMap = new Map(); -localStateMap.set(convertToKey('Local-key'), stringToBytes('Local-val')); +localStateMap.set(convertToKey('Local-key'), parsing.stringToBytes('Local-val')); export const accInfo = [{ address: "addr-1", diff --git a/packages/runtime/test/src/interpreter/opcode-list.ts b/packages/runtime/test/src/interpreter/opcode-list.ts index 1a7bd86f6..9fac358fc 100644 --- a/packages/runtime/test/src/interpreter/opcode-list.ts +++ b/packages/runtime/test/src/interpreter/opcode-list.ts @@ -1,5 +1,6 @@ /* eslint sonarjs/no-identical-functions: 0 */ /* eslint sonarjs/no-duplicate-string: 0 */ +import { parsing } from "@algo-builder/web"; import { decodeAddress, generateAccount, signBytes } from "algosdk"; import { assert } from "chai"; @@ -20,7 +21,7 @@ import { Select, SetBit, SetByte, Sha256, Sha512_256, Store, Sub, Substring, Substring3, Swap, Txn, Txna } from "../../../src/interpreter/opcode-list"; import { ALGORAND_ACCOUNT_MIN_BALANCE, ASSET_CREATION_FEE, DEFAULT_STACK_ELEM, MAX_UINT8, MAX_UINT64, MaxTEALVersion, MIN_UINT8 } from "../../../src/lib/constants"; -import { convertToBuffer, stringToBytes } from "../../../src/lib/parsing"; +import { convertToBuffer } from "../../../src/lib/parsing"; import { Stack } from "../../../src/lib/stack"; import { parseToStackElem } from "../../../src/lib/txn"; import { AccountStoreI, EncodingType, StackElem, Txn as EncodedTx } from "../../../src/types"; @@ -38,14 +39,14 @@ function setDummyAccInfo (acc: AccountStoreI): void { } describe("Teal Opcodes", function () { - const strArr = ["str1", "str2"].map(stringToBytes); + const strArr = ["str1", "str2"].map(parsing.stringToBytes); describe("Len", function () { const stack = new Stack(); it("should return correct length of string", function () { const str = "HelloWorld"; - stack.push(stringToBytes(str)); + stack.push(parsing.stringToBytes(str)); const op = new Len([], 0); op.execute(stack); @@ -219,7 +220,7 @@ describe("Teal Opcodes", function () { describe("Arg[N]", function () { const stack = new Stack(); let interpreter: Interpreter; - const args = ["Arg0", "Arg1", "Arg2", "Arg3"].map(stringToBytes); + const args = ["Arg0", "Arg1", "Arg2", "Arg3"].map(parsing.stringToBytes); this.beforeAll(() => { interpreter = new Interpreter(); @@ -292,7 +293,7 @@ describe("Teal Opcodes", function () { const expected: Uint8Array[] = []; for (const val of bytecblock) { - expected.push(stringToBytes(val)); + expected.push(parsing.stringToBytes(val)); } assert.deepEqual(expected, interpreter.bytecblock); }); @@ -301,7 +302,7 @@ describe("Teal Opcodes", function () { describe("Bytec[N]", function () { const stack = new Stack(); const interpreter = new Interpreter(); - const bytecblock = ["bytec_0", "bytec_1", "bytec_2", "bytec_3"].map(stringToBytes); + const bytecblock = ["bytec_0", "bytec_1", "bytec_2", "bytec_3"].map(parsing.stringToBytes); interpreter.bytecblock = bytecblock; it("should push bytec_0 from bytecblock to stack", function () { @@ -484,7 +485,7 @@ describe("Teal Opcodes", function () { it("should store byte[] to scratch", function () { const interpreter = new Interpreter(); - const val = stringToBytes("HelloWorld"); + const val = parsing.stringToBytes("HelloWorld"); stack.push(val); const op = new Store(["0"], 1, interpreter); @@ -605,7 +606,7 @@ describe("Teal Opcodes", function () { describe("Load", function () { const stack = new Stack(); const interpreter = new Interpreter(); - const scratch = [0n, stringToBytes("HelloWorld")]; + const scratch = [0n, parsing.stringToBytes("HelloWorld")]; interpreter.scratch = scratch; it("should load uint64 from scratch space to stack", function () { @@ -658,7 +659,7 @@ describe("Teal Opcodes", function () { const stack = new Stack(); it("should return correct hash for Sha256", () => { - stack.push(stringToBytes("MESSAGE")); + stack.push(parsing.stringToBytes("MESSAGE")); const op = new Sha256([], 1); op.execute(stack); @@ -682,7 +683,7 @@ describe("Teal Opcodes", function () { const stack = new Stack(); it("should return correct hash for Sha512_256", function () { - stack.push(stringToBytes("MESSAGE")); + stack.push(parsing.stringToBytes("MESSAGE")); const op = new Sha512_256([], 1); op.execute(stack); @@ -706,7 +707,7 @@ describe("Teal Opcodes", function () { const stack = new Stack(); it("should return correct hash for keccak256", function () { - stack.push(stringToBytes("ALGORAND")); + stack.push(parsing.stringToBytes("ALGORAND")); const op = new Keccak256([], 1); op.execute(stack); @@ -1241,7 +1242,7 @@ describe("Teal Opcodes", function () { it("should throw error if type is invalid", execExpectError( stack, - ["str1", "str2"].map(stringToBytes), + ["str1", "str2"].map(parsing.stringToBytes), new Mulw([], 1), RUNTIME_ERRORS.TEAL.INVALID_TYPE ) @@ -1300,13 +1301,13 @@ describe("Teal Opcodes", function () { let top = stack.pop(); assert.deepEqual(top, new Uint8Array([3, 2, 1, 1, 2, 3])); - stack.push(stringToBytes("Hello")); - stack.push(stringToBytes("Friend")); + stack.push(parsing.stringToBytes("Hello")); + stack.push(parsing.stringToBytes("Friend")); op = new Concat([], 1); op.execute(stack); top = stack.pop(); - assert.deepEqual(top, stringToBytes("HelloFriend")); + assert.deepEqual(top, parsing.stringToBytes("HelloFriend")); }); it("should throw error as byte strings too long", () => { @@ -1327,7 +1328,7 @@ describe("Teal Opcodes", function () { const end = "4"; it("should return correct substring", function () { - stack.push(stringToBytes("Algorand")); + stack.push(parsing.stringToBytes("Algorand")); const op = new Substring([start, end], 1); op.execute(stack); @@ -1345,7 +1346,7 @@ describe("Teal Opcodes", function () { ); it("should throw error if start is not uint8", function () { - stack.push(stringToBytes("Algorand")); + stack.push(parsing.stringToBytes("Algorand")); expectRuntimeError( () => new Substring([(MIN_UINT8 - 5).toString(), end], 1), @@ -1360,7 +1361,7 @@ describe("Teal Opcodes", function () { }); it("should throw error if end is not uint8", function () { - stack.push(stringToBytes("Algorand")); + stack.push(parsing.stringToBytes("Algorand")); expectRuntimeError( () => new Substring([start, (MIN_UINT8 - 5).toString()], 1), @@ -1377,7 +1378,7 @@ describe("Teal Opcodes", function () { it("should throw error because start > end", execExpectError( stack, - [stringToBytes("Algorand")], + [parsing.stringToBytes("Algorand")], new Substring(["9", end], 1), RUNTIME_ERRORS.TEAL.SUBSTRING_END_BEFORE_START ) @@ -1386,7 +1387,7 @@ describe("Teal Opcodes", function () { it("should throw error because range beyong string", execExpectError( stack, - [stringToBytes("Algorand")], + [parsing.stringToBytes("Algorand")], new Substring([start, "40"], 1), RUNTIME_ERRORS.TEAL.SUBSTRING_RANGE_BEYOND ) @@ -1399,7 +1400,7 @@ describe("Teal Opcodes", function () { it("should return correct substring", function () { stack.push(0n); stack.push(4n); - stack.push(stringToBytes("Algorand")); + stack.push(parsing.stringToBytes("Algorand")); const op = new Substring3([], 1); op.execute(stack); @@ -1422,7 +1423,7 @@ describe("Teal Opcodes", function () { const start = end + 1n; execExpectError( stack, - [start, end, stringToBytes("Algorand")], + [start, end, parsing.stringToBytes("Algorand")], new Substring3([], 1), RUNTIME_ERRORS.TEAL.SUBSTRING_END_BEFORE_START ); @@ -1431,7 +1432,7 @@ describe("Teal Opcodes", function () { it("should throw error because range beyong string", execExpectError( stack, - [0n, 40n, stringToBytes("Algorand")], + [0n, 40n, parsing.stringToBytes("Algorand")], new Substring3([], 1), RUNTIME_ERRORS.TEAL.SUBSTRING_RANGE_BEYOND ) @@ -1619,7 +1620,7 @@ describe("Teal Opcodes", function () { op.execute(stack); assert.equal(1, stack.length()); - assert.deepEqual(stringToBytes(TXN_OBJ.type), stack.pop()); + assert.deepEqual(parsing.stringToBytes(TXN_OBJ.type), stack.pop()); }); it("should push txn typeEnum to stack", function () { @@ -1798,7 +1799,7 @@ describe("Teal Opcodes", function () { op.execute(stack); assert.equal(1, stack.length()); - assert.deepEqual(stringToBytes(TXN_OBJ.apar.un), stack.pop()); + assert.deepEqual(parsing.stringToBytes(TXN_OBJ.apar.un), stack.pop()); }); it("should push txn ConfigAssetName to stack", function () { @@ -1806,7 +1807,7 @@ describe("Teal Opcodes", function () { op.execute(stack); assert.equal(1, stack.length()); - assert.deepEqual(stringToBytes(TXN_OBJ.apar.an), stack.pop()); + assert.deepEqual(parsing.stringToBytes(TXN_OBJ.apar.an), stack.pop()); }); it("should push txn ConfigAssetURL to stack", function () { @@ -1814,7 +1815,7 @@ describe("Teal Opcodes", function () { op.execute(stack); assert.equal(1, stack.length()); - assert.deepEqual(stringToBytes(TXN_OBJ.apar.au), stack.pop()); + assert.deepEqual(parsing.stringToBytes(TXN_OBJ.apar.au), stack.pop()); }); it("should push txn ConfigAssetMetadataHash to stack", function () { @@ -2491,29 +2492,29 @@ describe("Teal Opcodes", function () { it("should push the value to stack if key is present in local state", function () { // for Sender stack.push(0n); - stack.push(stringToBytes("Local-key")); + stack.push(parsing.stringToBytes("Local-key")); let op = new AppLocalGet([], 1, interpreter); op.execute(stack); let top = stack.pop(); - assert.deepEqual(stringToBytes('Local-val'), top); + assert.deepEqual(parsing.stringToBytes('Local-val'), top); // for Txn.Accounts[A] stack.push(1n); - stack.push(stringToBytes('Local-key')); + stack.push(parsing.stringToBytes('Local-key')); op = new AppLocalGet([], 1, interpreter); op.execute(stack); top = stack.pop(); - assert.deepEqual(stringToBytes('Local-val'), top); + assert.deepEqual(parsing.stringToBytes('Local-val'), top); }); it("should push uint 0 to stack if key is not present in local state", function () { // for Sender stack.push(0n); - stack.push(stringToBytes("random-key")); + stack.push(parsing.stringToBytes("random-key")); let op = new AppLocalGet([], 1, interpreter); op.execute(stack); @@ -2523,7 +2524,7 @@ describe("Teal Opcodes", function () { // for Txn.Accounts[A] stack.push(1n); - stack.push(stringToBytes('random-key')); + stack.push(parsing.stringToBytes('random-key')); op = new AppLocalGet([], 1, interpreter); op.execute(stack); @@ -2542,7 +2543,7 @@ describe("Teal Opcodes", function () { // for Sender stack.push(0n); stack.push(1847n); - stack.push(stringToBytes('Local-key')); + stack.push(parsing.stringToBytes('Local-key')); let op = new AppLocalGetEx([], 1, interpreter); op.execute(stack); @@ -2550,12 +2551,12 @@ describe("Teal Opcodes", function () { let flag = stack.pop(); let value = stack.pop(); assert.equal(1n, flag); - assert.deepEqual(stringToBytes('Local-val'), value); + assert.deepEqual(parsing.stringToBytes('Local-val'), value); // for Txn.Accounts[A] stack.push(1n); stack.push(1847n); - stack.push(stringToBytes('Local-key')); + stack.push(parsing.stringToBytes('Local-key')); op = new AppLocalGetEx([], 1, interpreter); op.execute(stack); @@ -2563,14 +2564,14 @@ describe("Teal Opcodes", function () { flag = stack.pop(); value = stack.pop(); assert.equal(1n, flag); - assert.deepEqual(stringToBytes('Local-val'), value); + assert.deepEqual(parsing.stringToBytes('Local-val'), value); }); it("should push uint 0 to stack if key is not present in local state from given appID", function () { // for Sender stack.push(0n); stack.push(1847n); - stack.push(stringToBytes('random-key')); + stack.push(parsing.stringToBytes('random-key')); let op = new AppLocalGetEx([], 1, interpreter); op.execute(stack); @@ -2583,7 +2584,7 @@ describe("Teal Opcodes", function () { // for Txn.Accounts[A] stack.push(1n); stack.push(1847n); - stack.push(stringToBytes('random-key')); + stack.push(parsing.stringToBytes('random-key')); op = new AppLocalGetEx([], 1, interpreter); op.execute(stack); @@ -2601,17 +2602,17 @@ describe("Teal Opcodes", function () { }); it("should push the value to stack if key is present in global state", function () { - stack.push(stringToBytes('global-key')); + stack.push(parsing.stringToBytes('global-key')); const op = new AppGlobalGet([], 1, interpreter); op.execute(stack); const top = stack.pop(); - assert.deepEqual(stringToBytes('global-val'), top); + assert.deepEqual(parsing.stringToBytes('global-val'), top); }); it("should push uint 0 to stack if key is not present in global state", function () { - stack.push(stringToBytes('random-key')); + stack.push(parsing.stringToBytes('random-key')); const op = new AppGlobalGet([], 1, interpreter); op.execute(stack); @@ -2629,7 +2630,7 @@ describe("Teal Opcodes", function () { it("should push the value to stack if key is present externally in global state", function () { // zero index means current app stack.push(0n); - stack.push(stringToBytes('Hello')); + stack.push(parsing.stringToBytes('Hello')); let op = new AppGlobalGetEx([], 1, interpreter); op.execute(stack); @@ -2637,11 +2638,11 @@ describe("Teal Opcodes", function () { let flag = stack.pop(); let value = stack.pop(); assert.equal(1n, flag); - assert.deepEqual(stringToBytes('World'), value); + assert.deepEqual(parsing.stringToBytes('World'), value); // for Txn.ForeignApps[A] stack.push(1n); - stack.push(stringToBytes('global-key')); + stack.push(parsing.stringToBytes('global-key')); op = new AppGlobalGetEx([], 1, interpreter); op.execute(stack); @@ -2649,13 +2650,13 @@ describe("Teal Opcodes", function () { flag = stack.pop(); value = stack.pop(); assert.equal(1n, flag); - assert.deepEqual(stringToBytes('global-val'), value); + assert.deepEqual(parsing.stringToBytes('global-val'), value); }); it("should push uint 0 to stack if key is not present externally in global state", function () { // zero index means current app stack.push(0n); - stack.push(stringToBytes('random-key')); + stack.push(parsing.stringToBytes('random-key')); let op = new AppGlobalGetEx([], 1, interpreter); op.execute(stack); @@ -2667,7 +2668,7 @@ describe("Teal Opcodes", function () { // for Txn.ForeignApps[A] stack.push(1n); - stack.push(stringToBytes('random-key')); + stack.push(parsing.stringToBytes('random-key')); op = new AppGlobalGetEx([], 1, interpreter); op.execute(stack); @@ -2688,8 +2689,8 @@ describe("Teal Opcodes", function () { let value; // for Sender, check for byte stack.push(0n); - stack.push(stringToBytes('New-Key')); - stack.push(stringToBytes('New-Val')); + stack.push(parsing.stringToBytes('New-Key')); + stack.push(parsing.stringToBytes('New-Val')); let op = new AppLocalPut([], 1, interpreter); op.execute(stack); @@ -2699,11 +2700,11 @@ describe("Teal Opcodes", function () { value = acc.getLocalState(appID, 'New-Key'); assert.isDefined(value); - assert.deepEqual(value, stringToBytes('New-Val')); + assert.deepEqual(value, parsing.stringToBytes('New-Val')); // for Txn.Accounts[A], uint stack.push(1n); - stack.push(stringToBytes('New-Key-1')); + stack.push(parsing.stringToBytes('New-Key-1')); stack.push(2222n); op = new AppLocalPut([], 1, interpreter); @@ -2719,7 +2720,7 @@ describe("Teal Opcodes", function () { // so this should throw error execExpectError( stack, - [0n, stringToBytes("New-Key-1"), stringToBytes("New-Val-2")], + [0n, parsing.stringToBytes("New-Key-1"), parsing.stringToBytes("New-Val-2")], new AppLocalPut([], 1, interpreter), RUNTIME_ERRORS.TEAL.INVALID_SCHEMA ); @@ -2729,7 +2730,7 @@ describe("Teal Opcodes", function () { interpreter.runtime.ctx.tx.apid = 9999; execExpectError( stack, - [0n, stringToBytes("New-Key-1"), stringToBytes("New-Val-2")], + [0n, parsing.stringToBytes("New-Key-1"), parsing.stringToBytes("New-Val-2")], new AppLocalPut([], 1, interpreter), RUNTIME_ERRORS.TEAL.APP_NOT_FOUND ); @@ -2744,18 +2745,18 @@ describe("Teal Opcodes", function () { it("should put the value in global storage", function () { // value as byte - stack.push(stringToBytes('New-Global-Key')); - stack.push(stringToBytes('New-Global-Val')); + stack.push(parsing.stringToBytes('New-Global-Key')); + stack.push(parsing.stringToBytes('New-Global-Val')); let op = new AppGlobalPut([], 1, interpreter); op.execute(stack); let value = interpreter.getGlobalState(appID, 'New-Global-Key', lineNumber); assert.isDefined(value); // idx should not be -1 - assert.deepEqual(value, stringToBytes('New-Global-Val')); + assert.deepEqual(value, parsing.stringToBytes('New-Global-Val')); // for uint - stack.push(stringToBytes('Key')); + stack.push(parsing.stringToBytes('Key')); stack.push(1000n); op = new AppGlobalPut([], 1, interpreter); @@ -2769,7 +2770,7 @@ describe("Teal Opcodes", function () { it("should throw error if resulting schema is invalid for global", function () { execExpectError( stack, - [stringToBytes("New-GlobalKey-1"), stringToBytes("New-GlobalVal-2")], + [parsing.stringToBytes("New-GlobalKey-1"), parsing.stringToBytes("New-GlobalVal-2")], new AppGlobalPut([], 1, interpreter), RUNTIME_ERRORS.TEAL.INVALID_SCHEMA ); @@ -2779,7 +2780,7 @@ describe("Teal Opcodes", function () { interpreter.runtime.ctx.tx.apid = 9999; execExpectError( stack, - [stringToBytes("New-Key-1"), stringToBytes("New-Val-2")], + [parsing.stringToBytes("New-Key-1"), parsing.stringToBytes("New-Val-2")], new AppGlobalPut([], 1, interpreter), RUNTIME_ERRORS.TEAL.APP_NOT_FOUND ); @@ -2794,7 +2795,7 @@ describe("Teal Opcodes", function () { it("should remove the key-value pair from account's local storage", function () { // for Sender stack.push(0n); - stack.push(stringToBytes('Local-key')); + stack.push(parsing.stringToBytes('Local-key')); let op = new AppLocalDel([], 1, interpreter); op.execute(stack); @@ -2806,7 +2807,7 @@ describe("Teal Opcodes", function () { // for Txn.Accounts[A] stack.push(1n); - stack.push(stringToBytes('Local-key')); + stack.push(parsing.stringToBytes('Local-key')); op = new AppLocalDel([], 1, interpreter); op.execute(stack); @@ -2824,7 +2825,7 @@ describe("Teal Opcodes", function () { it("should remove the key-value pair from global storage", function () { stack.push(0n); - stack.push(stringToBytes('global-key')); + stack.push(parsing.stringToBytes('global-key')); const op = new AppGlobalDel([], 1, interpreter); op.execute(stack); @@ -3292,7 +3293,7 @@ describe("Teal Opcodes", function () { RUNTIME_ERRORS.TEAL.TEAL_ENCOUNTERED_ERR ); - stack.push(stringToBytes("HelloWorld")); + stack.push(parsing.stringToBytes("HelloWorld")); expectRuntimeError( () => op.execute(stack), RUNTIME_ERRORS.TEAL.INVALID_TYPE @@ -3324,22 +3325,22 @@ describe("Teal Opcodes", function () { assert.equal(stack.pop(), 10n); op = new Swap([], 0); - stack.push(stringToBytes("hello")); - stack.push(stringToBytes("world")); + stack.push(parsing.stringToBytes("hello")); + stack.push(parsing.stringToBytes("world")); op.execute(stack); assert.equal(stack.length(), 2); - assert.deepEqual(stack.pop(), stringToBytes("hello")); - assert.deepEqual(stack.pop(), stringToBytes("world")); + assert.deepEqual(stack.pop(), parsing.stringToBytes("hello")); + assert.deepEqual(stack.pop(), parsing.stringToBytes("world")); op = new Swap([], 0); stack.push(5n); - stack.push(stringToBytes("a")); + stack.push(parsing.stringToBytes("a")); op.execute(stack); assert.equal(stack.length(), 2); assert.deepEqual(stack.pop(), 5n); - assert.deepEqual(stack.pop(), stringToBytes("a")); + assert.deepEqual(stack.pop(), parsing.stringToBytes("a")); }); it("should throw error if length of stack < 2", () => { @@ -3772,21 +3773,21 @@ describe("Teal Opcodes", function () { assert.equal(stack.pop(), 5n); op = new Dig(["1"], 0); - stack.push(stringToBytes("hello")); - stack.push(stringToBytes("world")); + stack.push(parsing.stringToBytes("hello")); + stack.push(parsing.stringToBytes("world")); op.execute(stack); assert.equal(stack.length(), 3); - assert.deepEqual(stack.pop(), stringToBytes("hello")); + assert.deepEqual(stack.pop(), parsing.stringToBytes("hello")); }); it("should duplicate nth slot from top of stack (mixed cases)", () => { stack.push(5n); stack.push(10n); - stack.push(stringToBytes("hello")); - stack.push(stringToBytes("world")); + stack.push(parsing.stringToBytes("hello")); + stack.push(parsing.stringToBytes("world")); stack.push(0n); - stack.push(stringToBytes("Algorand")); + stack.push(parsing.stringToBytes("Algorand")); stack.push(0n); // stack looks like: [...stack, 5n, 10n, "hello", "world", 0n, "Algorand", 0n] @@ -3794,7 +3795,7 @@ describe("Teal Opcodes", function () { let op = new Dig(["4"], 0); op.execute(stack); assert.equal(stack.length(), len + 1); - assert.deepEqual(stack.pop(), stringToBytes("hello")); + assert.deepEqual(stack.pop(), parsing.stringToBytes("hello")); op = new Dig(["6"], 0); op.execute(stack); @@ -3804,12 +3805,12 @@ describe("Teal Opcodes", function () { op = new Dig(["3"], 0); op.execute(stack); assert.equal(stack.length(), len + 1); - assert.deepEqual(stack.pop(), stringToBytes("world")); + assert.deepEqual(stack.pop(), parsing.stringToBytes("world")); op = new Dig(["1"], 0); op.execute(stack); assert.equal(stack.length(), len + 1); - assert.deepEqual(stack.pop(), stringToBytes("Algorand")); + assert.deepEqual(stack.pop(), parsing.stringToBytes("Algorand")); }); it("should panic if depth of stack is insufficient", () => { @@ -3830,16 +3831,16 @@ describe("Teal Opcodes", function () { it("should push '2nd element from top of stack' to stack if top is not zero", () => { let op = new Select([], 0); - stack.push(stringToBytes("lionel")); - stack.push(stringToBytes("messi")); + stack.push(parsing.stringToBytes("lionel")); + stack.push(parsing.stringToBytes("messi")); stack.push(7n); // top is non-zero element op.execute(stack); assert.equal(stack.length(), 1); - assert.deepEqual(stack.pop(), stringToBytes("messi")); + assert.deepEqual(stack.pop(), parsing.stringToBytes("messi")); op = new Select([], 0); - stack.push(stringToBytes("lionel")); + stack.push(parsing.stringToBytes("lionel")); stack.push(100n); stack.push(7n); @@ -3850,17 +3851,17 @@ describe("Teal Opcodes", function () { it("should push '3rd element from top of stack' to stack if top is zero", () => { let op = new Select([], 0); - stack.push(stringToBytes("lionel")); - stack.push(stringToBytes("messi")); + stack.push(parsing.stringToBytes("lionel")); + stack.push(parsing.stringToBytes("messi")); stack.push(0n); // top is zero op.execute(stack); assert.equal(stack.length(), 1); - assert.deepEqual(stack.pop(), stringToBytes("lionel")); + assert.deepEqual(stack.pop(), parsing.stringToBytes("lionel")); op = new Select([], 0); stack.push(100n); - stack.push(stringToBytes("messi")); + stack.push(parsing.stringToBytes("messi")); stack.push(0n); op.execute(stack); @@ -3870,7 +3871,7 @@ describe("Teal Opcodes", function () { it("should panic if length of stack is < 3", () => { const op = new Select([], 0); - stack.push(stringToBytes("lionel")); + stack.push(parsing.stringToBytes("lionel")); stack.push(0n); expectRuntimeError( @@ -3881,9 +3882,9 @@ describe("Teal Opcodes", function () { it("should panic if top of stack is not uint64", () => { const op = new Select([], 0); - stack.push(stringToBytes("lionel")); - stack.push(stringToBytes("andres")); - stack.push(stringToBytes("messi")); + stack.push(parsing.stringToBytes("lionel")); + stack.push(parsing.stringToBytes("andres")); + stack.push(parsing.stringToBytes("messi")); expectRuntimeError( () => op.execute(stack), @@ -3938,7 +3939,7 @@ describe("Teal Opcodes", function () { op = new Gtxns(["ApplicationArgs", "2"], 1, interpreter); op.execute(stack); assert.equal(1, stack.length()); - assert.deepEqual(stringToBytes("argC"), stack.pop()); + assert.deepEqual(parsing.stringToBytes("argC"), stack.pop()); }); it("Gtxns: should panic if length of stack is < 1", () => { @@ -3963,13 +3964,13 @@ describe("Teal Opcodes", function () { let op = new Gtxnsa(["ApplicationArgs", "1"], 1, interpreter); op.execute(stack); assert.equal(1, stack.length()); - assert.deepEqual(stringToBytes("arg2"), stack.pop()); // args from tx0 + assert.deepEqual(parsing.stringToBytes("arg2"), stack.pop()); // args from tx0 stack.push(1n); op = new Gtxnsa(["ApplicationArgs", "0"], 1, interpreter); op.execute(stack); assert.equal(1, stack.length()); - assert.deepEqual(stringToBytes("argA"), stack.pop()); // args from tx1 + assert.deepEqual(parsing.stringToBytes("argA"), stack.pop()); // args from tx1 }); it("Gtxnsa: should panic if index is out of bounds for txFieldArr", () => { diff --git a/packages/runtime/test/src/interpreter/opcode.ts b/packages/runtime/test/src/interpreter/opcode.ts index 94224249f..ef7ebba2d 100644 --- a/packages/runtime/test/src/interpreter/opcode.ts +++ b/packages/runtime/test/src/interpreter/opcode.ts @@ -1,7 +1,8 @@ +import { parsing } from "@algo-builder/web"; + import { RUNTIME_ERRORS } from "../../../src/errors/errors-list"; import { Op } from "../../../src/interpreter/opcode"; import { MAX_UINT64, MIN_UINT64 } from "../../../src/lib/constants"; -import { stringToBytes } from "../../../src/lib/parsing"; import { Stack } from "../../../src/lib/stack"; import type { StackElem } from "../../../src/types"; import { expectRuntimeError } from "../../helpers/runtime-errors"; @@ -35,7 +36,7 @@ describe("Teal Opcodes basic assertions", function () { let lineNumber = 1; op.assertMinStackLen(stack, stackLen, lineNumber); - stack.push(stringToBytes("arg_0")); + stack.push(parsing.stringToBytes("arg_0")); stackLen = 2; lineNumber = 1; expectRuntimeError( diff --git a/packages/runtime/test/src/interpreter/stack.ts b/packages/runtime/test/src/interpreter/stack.ts index eadae06d4..67399e8c8 100644 --- a/packages/runtime/test/src/interpreter/stack.ts +++ b/packages/runtime/test/src/interpreter/stack.ts @@ -1,6 +1,6 @@ +import { parsing } from "@algo-builder/web"; import { assert } from "chai"; -import { stringToBytes } from "../../../src"; import { Stack } from "../../../src/lib/stack"; import { StackElem } from "../../../src/types"; @@ -26,11 +26,11 @@ describe("Stack", function () { it("should push bigint and bytes", function () { stack.push(10n); - stack.push(stringToBytes("txn")); + stack.push(parsing.stringToBytes("txn")); const str = stack.pop(); const num = stack.pop(); - assert.deepEqual(str, stringToBytes("txn")); + assert.deepEqual(str, parsing.stringToBytes("txn")); assert.equal(num, 10n); }); @@ -38,13 +38,13 @@ describe("Stack", function () { stack.push(1n); stack.push(2n); stack.push(3n); - stack.push(stringToBytes("pulp")); - stack.push(stringToBytes("fiction")); + stack.push(parsing.stringToBytes("pulp")); + stack.push(parsing.stringToBytes("fiction")); let newStack = stack.debug(2); assert.equal(newStack.length, 2); - assert.deepEqual(newStack[0], stringToBytes("fiction")); // top - assert.deepEqual(newStack[1], stringToBytes("pulp")); // 2nd elem from top + assert.deepEqual(newStack[0], parsing.stringToBytes("fiction")); // top + assert.deepEqual(newStack[1], parsing.stringToBytes("pulp")); // 2nd elem from top newStack = stack.debug(200); // should return an array of all stack elements assert.equal(newStack.length, stack.length()); diff --git a/packages/runtime/test/src/lib/asa.ts b/packages/runtime/test/src/lib/asa.ts index 457878f9e..2371668c3 100644 --- a/packages/runtime/test/src/lib/asa.ts +++ b/packages/runtime/test/src/lib/asa.ts @@ -1,8 +1,9 @@ +import { types } from "@algo-builder/web"; import { assert } from "chai"; import { RUNTIME_ERRORS } from "../../../src/errors/errors-list"; import { validateASADefs } from "../../../src/lib/asa"; -import { Account, ASADefs } from "../../../src/types"; +import { Account } from "../../../src/types"; import { expectRuntimeError } from "../../helpers/runtime-errors"; const namedAccount: Account = { @@ -13,7 +14,7 @@ const namedAccount: Account = { describe("ASA parser", () => { it("Should validate correct obj", async () => { - const valid: ASADefs = { + const valid: types.ASADefs = { A1: { total: 1, decimals: 0, diff --git a/packages/runtime/test/src/lib/parsing.ts b/packages/runtime/test/src/lib/parsing.ts index 2b5104fce..45b017148 100644 --- a/packages/runtime/test/src/lib/parsing.ts +++ b/packages/runtime/test/src/lib/parsing.ts @@ -1,8 +1,9 @@ +import { parsing } from "@algo-builder/web"; import { decodeAddress } from "algosdk"; import { assert } from "chai"; import { MAX_UINT64, MIN_UINT64 } from "../../../src/lib/constants"; -import { convertToString, parseSSCAppArgs, stringToBytes, uint64ToBigEndian } from "../../../src/lib/parsing"; +import { convertToString } from "../../../src/lib/parsing"; describe("Convert integer to big endian", () => { /** @@ -13,87 +14,87 @@ describe("Convert integer to big endian", () => { * fmt.Println(buf) */ it("should return correct big endian for 64 bit integer", () => { - let res = uint64ToBigEndian(0); + let res = parsing.uint64ToBigEndian(0); let expected = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]); assert.deepEqual(res, expected); - res = uint64ToBigEndian(20); + res = parsing.uint64ToBigEndian(20); expected = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 20]); assert.deepEqual(res, expected); - res = uint64ToBigEndian(700000000); + res = parsing.uint64ToBigEndian(700000000); expected = new Uint8Array([0, 0, 0, 0, 41, 185, 39, 0]); assert.deepEqual(res, expected); - res = uint64ToBigEndian(233654); + res = parsing.uint64ToBigEndian(233654); expected = new Uint8Array([0, 0, 0, 0, 0, 3, 144, 182]); assert.deepEqual(res, expected); - res = uint64ToBigEndian(Number.MAX_SAFE_INTEGER); + res = parsing.uint64ToBigEndian(Number.MAX_SAFE_INTEGER); expected = new Uint8Array([0, 31, 255, 255, 255, 255, 255, 255]); assert.deepEqual(res, expected); // passing bigint in tests below - res = uint64ToBigEndian(MIN_UINT64); + res = parsing.uint64ToBigEndian(MIN_UINT64); expected = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]); assert.deepEqual(res, expected); - res = uint64ToBigEndian(233654n); + res = parsing.uint64ToBigEndian(233654n); expected = new Uint8Array([0, 0, 0, 0, 0, 3, 144, 182]); assert.deepEqual(res, expected); - res = uint64ToBigEndian(18446744073709551055n); + res = parsing.uint64ToBigEndian(18446744073709551055n); expected = new Uint8Array([255, 255, 255, 255, 255, 255, 253, 207]); assert.deepEqual(res, expected); - res = uint64ToBigEndian(18446744073709111055n); + res = parsing.uint64ToBigEndian(18446744073709111055n); expected = new Uint8Array([255, 255, 255, 255, 255, 249, 71, 15]); assert.deepEqual(res, expected); - res = uint64ToBigEndian(MAX_UINT64); + res = parsing.uint64ToBigEndian(MAX_UINT64); expected = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]); assert.deepEqual(res, expected); }); it("should throw error if value is not uint64", () => { let errMsg = "Invalid uint64 -5"; - assert.throws(() => uint64ToBigEndian(MIN_UINT64 - 5n), errMsg); + assert.throws(() => parsing.uint64ToBigEndian(MIN_UINT64 - 5n), errMsg); errMsg = "Invalid uint64 18446744073709551620"; - assert.throws(() => uint64ToBigEndian(MAX_UINT64 + 5n), errMsg); + assert.throws(() => parsing.uint64ToBigEndian(MAX_UINT64 + 5n), errMsg); }); }); describe("Parse string and integer, with bytes", () => { it("string identity should be equal ", () => { let initialString = "50"; - let stringInBytes = stringToBytes(initialString); + let stringInBytes = parsing.stringToBytes(initialString); let backToString = convertToString(stringInBytes); assert.equal(backToString, initialString); initialString = "TEAL_CODE"; - stringInBytes = stringToBytes(initialString); + stringInBytes = parsing.stringToBytes(initialString); backToString = convertToString(stringInBytes); assert.equal(backToString, initialString); }); }); -describe("Parse appArgs to SSC to bytes", () => { +describe("Parse appArgs to App to bytes", () => { it("should return undefined if app Args are not defined", () => { - const res = parseSSCAppArgs(undefined); + const res = parsing.parseAppArgs(undefined); assert.isUndefined(res); }); it("should return same bytes if all bytes are passed", () => { - const res = parseSSCAppArgs(['a', 'b', 'c'].map(stringToBytes)); + const res = parsing.parseAppArgs(['a', 'b', 'c'].map(parsing.stringToBytes)); const expected = [[97], [98], [99]].map(z => new Uint8Array(z)); assert.deepEqual(res, expected); }); it("should return correct bytes if args are passed similar to goal", () => { - let res = parseSSCAppArgs(['int:700000000', 'int:3', `int:${MAX_UINT64}`]); + let res = parsing.parseAppArgs(['int:700000000', 'int:3', `int:${MAX_UINT64}`]); let expected = [ [0, 0, 0, 0, 41, 185, 39, 0], [0, 0, 0, 0, 0, 0, 0, 3], @@ -101,7 +102,7 @@ describe("Parse appArgs to SSC to bytes", () => { ].map(z => new Uint8Array(z)); assert.deepEqual(res, expected); - res = parseSSCAppArgs(['str:hello', 'str:world']); + res = parsing.parseAppArgs(['str:hello', 'str:world']); expected = [ [104, 101, 108, 108, 111], // 'hello' [119, 111, 114, 108, 100] // 'world' @@ -110,31 +111,31 @@ describe("Parse appArgs to SSC to bytes", () => { const elon = 'WHVQXVVCQAD7WX3HHFKNVUL3MOANX3BYXXMEEJEJWOZNRXJNTN7LTNPSTY'; const john = '2UBZKFR6RCZL7R24ZG327VKPTPJUPFM6WTG7PJG2ZJLU234F5RGXFLTAKA'; - res = parseSSCAppArgs([`addr:${elon}`, `addr:${john}`]); + res = parsing.parseAppArgs([`addr:${elon}`, `addr:${john}`]); expected = [elon, john].map(s => decodeAddress(s).publicKey); assert.deepEqual(res, expected); - res = parseSSCAppArgs(['b64:a2F0cmluYQ==', 'b64:YmVubmV0']); + res = parsing.parseAppArgs(['b64:a2F0cmluYQ==', 'b64:YmVubmV0']); expected = [ 'katrina', // 'katrina' encoded as b64 is a2F0cmluYQ== 'bennet' // 'bennet' encoded as b64 is YmVubmV0 - ].map(z => stringToBytes(z)); + ].map(z => parsing.stringToBytes(z)); assert.deepEqual(res, expected); }); it("should throw error if passed args are invalid", () => { const errMsg = (str: string): string => { return `Format of arguments passed to stateful smart is invalid for ${str}`; }; - assert.throws(() => parseSSCAppArgs(['INT:12']), errMsg('INT:12')); - assert.throws(() => parseSSCAppArgs(['intt:1']), errMsg('intt:1')); - assert.throws(() => parseSSCAppArgs(['int:abcd']), errMsg('int:abcd')); // type is correct but value is string - assert.throws(() => parseSSCAppArgs(['string:hello']), errMsg('string:hello')); - assert.throws(() => parseSSCAppArgs(['address:ABCD']), errMsg('address:ABCD')); - assert.throws(() => parseSSCAppArgs(['base64:===']), errMsg('base64:===')); - assert.throws(() => parseSSCAppArgs(['STR:abc']), errMsg('STR:abc')); - assert.throws(() => parseSSCAppArgs(['ADRR:XYZ']), errMsg('ADRR:XYZ')); + assert.throws(() => parsing.parseAppArgs(['INT:12']), errMsg('INT:12')); + assert.throws(() => parsing.parseAppArgs(['intt:1']), errMsg('intt:1')); + assert.throws(() => parsing.parseAppArgs(['int:abcd']), errMsg('int:abcd')); // type is correct but value is string + assert.throws(() => parsing.parseAppArgs(['string:hello']), errMsg('string:hello')); + assert.throws(() => parsing.parseAppArgs(['address:ABCD']), errMsg('address:ABCD')); + assert.throws(() => parsing.parseAppArgs(['base64:===']), errMsg('base64:===')); + assert.throws(() => parsing.parseAppArgs(['STR:abc']), errMsg('STR:abc')); + assert.throws(() => parsing.parseAppArgs(['ADRR:XYZ']), errMsg('ADRR:XYZ')); const errorMsg = 'Invalid uint64 18446744073709551625'; - assert.throws(() => parseSSCAppArgs([`int:${MAX_UINT64 + 10n}`]), errorMsg); + assert.throws(() => parsing.parseAppArgs([`int:${MAX_UINT64 + 10n}`]), errorMsg); }); }); diff --git a/packages/runtime/test/src/runtime.ts b/packages/runtime/test/src/runtime.ts index 9b5e1a8c8..2034d689e 100644 --- a/packages/runtime/test/src/runtime.ts +++ b/packages/runtime/test/src/runtime.ts @@ -1,3 +1,4 @@ +import { types } from "@algo-builder/web"; import { LogicSig } from "algosdk"; import { assert } from "chai"; import sinon from "sinon"; @@ -6,8 +7,6 @@ import { AccountStore } from "../../src/account"; import { RUNTIME_ERRORS } from "../../src/errors/errors-list"; import { ASSET_CREATION_FEE } from "../../src/lib/constants"; import { Runtime } from "../../src/runtime"; -import type { AlgoTransferParam, AssetModFields, AssetTransferParam, DestroyAssetParam, ExecParams, FreezeAssetParam, ModifyAssetParam, RevokeAssetParam } from "../../src/types"; -import { SignType, TransactionType } from "../../src/types"; import { getProgram } from "../helpers/files"; import { useFixture } from "../helpers/integration"; import { expectRuntimeError } from "../helpers/runtime-errors"; @@ -24,13 +23,13 @@ describe("Logic Signature Transaction in Runtime", function () { let runtime: Runtime; let lsig: LogicSig; - let txnParam: ExecParams; + let txnParam: types.ExecParams; this.beforeAll(function () { runtime = new Runtime([john, bob, alice]); lsig = runtime.getLogicSig(getProgram(programName), []); txnParam = { - type: TransactionType.TransferAlgo, - sign: SignType.LogicSignature, + type: types.TransactionType.TransferAlgo, + sign: types.SignType.LogicSignature, fromAccountAddr: john.account.addr, toAccountAddr: bob.account.addr, amountMicroAlgos: 1000n, @@ -49,9 +48,9 @@ describe("Logic Signature Transaction in Runtime", function () { }); it("should not verify signature because alice sent it", () => { - const invalidParams: ExecParams = { + const invalidParams: types.ExecParams = { ...txnParam, - sign: SignType.LogicSignature, + sign: types.SignType.LogicSignature, fromAccountAddr: alice.account.addr, lsig: lsig }; @@ -65,9 +64,9 @@ describe("Logic Signature Transaction in Runtime", function () { it("should verify signature but reject logic", async () => { const logicSig = runtime.getLogicSig(getProgram("reject.teal"), []); - const txParams: ExecParams = { + const txParams: types.ExecParams = { ...txnParam, - sign: SignType.LogicSignature, + sign: types.SignType.LogicSignature, fromAccountAddr: john.account.addr, lsig: logicSig }; @@ -88,14 +87,14 @@ describe("Rounds Test", function () { let john = new AccountStore(minBalance); let bob = new AccountStore(minBalance); let runtime: Runtime; - let txnParams: AlgoTransferParam; + let txnParams: types.AlgoTransferParam; this.beforeAll(function () { runtime = new Runtime([john, bob]); // setup test // set up transaction paramenters txnParams = { - type: TransactionType.TransferAlgo, // payment - sign: SignType.SecretKey, + type: types.TransactionType.TransferAlgo, // payment + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: bob.address, amountMicroAlgos: 100n, @@ -109,7 +108,7 @@ describe("Rounds Test", function () { runtime = new Runtime([john, bob]); txnParams = { ...txnParams, - sign: SignType.SecretKey, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: bob.address }; @@ -160,8 +159,8 @@ describe("Algorand Standard Assets", function () { let alice = new AccountStore(minBalance); const elon = new AccountStore(minBalance, elonMuskAccount); let runtime: Runtime; - let modFields: AssetModFields; - let assetTransferParam: AssetTransferParam; + let modFields: types.AssetModFields; + let assetTransferParam: types.AssetTransferParam; let assetId: number; this.beforeAll(() => { runtime = new Runtime([john, bob, alice, elon]); @@ -172,8 +171,8 @@ describe("Algorand Standard Assets", function () { freeze: john.address }; assetTransferParam = { - type: TransactionType.TransferAsset, - sign: SignType.SecretKey, + type: types.TransactionType.TransferAsset, + sign: types.SignType.SecretKey, fromAccount: john.account, toAccountAddr: alice.account.addr, amount: 10n, @@ -268,9 +267,9 @@ describe("Algorand Standard Assets", function () { }); it("should throw error on transfer asset if asset is frozen and amount > 0", () => { - const freezeParam: FreezeAssetParam = { - type: TransactionType.FreezeAsset, - sign: SignType.SecretKey, + const freezeParam: types.FreezeAssetParam = { + type: types.TransactionType.FreezeAsset, + sign: types.SignType.SecretKey, fromAccount: elon.account, assetID: assetId, freezeTarget: john.address, @@ -318,7 +317,7 @@ describe("Algorand Standard Assets", function () { runtime.executeTx({ ...assetTransferParam, - sign: SignType.SecretKey, + sign: types.SignType.SecretKey, fromAccount: alice.account, toAccountAddr: alice.address, payFlags: { totalFee: 1000, closeRemainderTo: john.address } // transfer all assets of alice => john (using closeRemTo) @@ -345,9 +344,9 @@ describe("Algorand Standard Assets", function () { }); it("should throw error if asset is not found while modifying", () => { - const modifyParam: ModifyAssetParam = { - type: TransactionType.ModifyAsset, - sign: SignType.SecretKey, + const modifyParam: types.ModifyAssetParam = { + type: types.TransactionType.ModifyAsset, + sign: types.SignType.SecretKey, fromAccount: john.account, assetID: 120, fields: modFields, @@ -360,9 +359,9 @@ describe("Algorand Standard Assets", function () { }); it("should modify asset", () => { - const modifyParam: ModifyAssetParam = { - type: TransactionType.ModifyAsset, - sign: SignType.SecretKey, + const modifyParam: types.ModifyAssetParam = { + type: types.TransactionType.ModifyAsset, + sign: types.SignType.SecretKey, fromAccount: elon.account, assetID: assetId, fields: modFields, @@ -381,15 +380,15 @@ describe("Algorand Standard Assets", function () { const assetId = runtime.addAsset('silver', { creator: { ...john.account, name: "john" } }); - const modFields: AssetModFields = { + const modFields: types.AssetModFields = { manager: bob.address, reserve: bob.address, clawback: john.address, freeze: alice.address }; - const modifyParam: ModifyAssetParam = { - type: TransactionType.ModifyAsset, - sign: SignType.SecretKey, + const modifyParam: types.ModifyAssetParam = { + type: types.TransactionType.ModifyAsset, + sign: types.SignType.SecretKey, fromAccount: elon.account, assetID: assetId, fields: modFields, @@ -403,9 +402,9 @@ describe("Algorand Standard Assets", function () { }); it("should fail because only manager account can modify asset", () => { - const modifyParam: ModifyAssetParam = { - type: TransactionType.ModifyAsset, - sign: SignType.SecretKey, + const modifyParam: types.ModifyAssetParam = { + type: types.TransactionType.ModifyAsset, + sign: types.SignType.SecretKey, fromAccount: bob.account, assetID: assetId, fields: modFields, @@ -418,9 +417,9 @@ describe("Algorand Standard Assets", function () { }); it("should fail because only freeze account can freeze asset", () => { - const freezeParam: FreezeAssetParam = { - type: TransactionType.FreezeAsset, - sign: SignType.SecretKey, + const freezeParam: types.FreezeAssetParam = { + type: types.TransactionType.FreezeAsset, + sign: types.SignType.SecretKey, fromAccount: bob.account, assetID: assetId, freezeTarget: john.address, @@ -435,9 +434,9 @@ describe("Algorand Standard Assets", function () { }); it("should freeze asset", () => { - const freezeParam: FreezeAssetParam = { - type: TransactionType.FreezeAsset, - sign: SignType.SecretKey, + const freezeParam: types.FreezeAssetParam = { + type: types.TransactionType.FreezeAsset, + sign: types.SignType.SecretKey, fromAccount: elon.account, assetID: assetId, freezeTarget: john.address, @@ -451,9 +450,9 @@ describe("Algorand Standard Assets", function () { }); it("should fail because only clawback account can revoke assets", () => { - const revokeParam: RevokeAssetParam = { - type: TransactionType.RevokeAsset, - sign: SignType.SecretKey, + const revokeParam: types.RevokeAssetParam = { + type: types.TransactionType.RevokeAsset, + sign: types.SignType.SecretKey, fromAccount: alice.account, recipient: john.address, assetID: assetId, @@ -468,9 +467,9 @@ describe("Algorand Standard Assets", function () { }); it("should revoke assets", () => { - const revokeParam: RevokeAssetParam = { - type: TransactionType.RevokeAsset, - sign: SignType.SecretKey, + const revokeParam: types.RevokeAssetParam = { + type: types.TransactionType.RevokeAsset, + sign: types.SignType.SecretKey, fromAccount: elon.account, recipient: john.address, assetID: assetId, @@ -499,9 +498,9 @@ describe("Algorand Standard Assets", function () { }); it("should fail because only clawback account can revoke assets", () => { - const revokeParam: RevokeAssetParam = { - type: TransactionType.RevokeAsset, - sign: SignType.SecretKey, + const revokeParam: types.RevokeAssetParam = { + type: types.TransactionType.RevokeAsset, + sign: types.SignType.SecretKey, fromAccount: alice.account, recipient: john.address, assetID: assetId, @@ -516,9 +515,9 @@ describe("Algorand Standard Assets", function () { }); it("should throw error if trying to close asset holding by clawback", () => { /* eslint sonarjs/no-identical-functions: "off" */ - const closebyClawbackParam: RevokeAssetParam = { - type: TransactionType.RevokeAsset, - sign: SignType.SecretKey, + const closebyClawbackParam: types.RevokeAssetParam = { + type: types.TransactionType.RevokeAsset, + sign: types.SignType.SecretKey, fromAccount: elon.account, recipient: john.address, assetID: assetId, @@ -536,18 +535,18 @@ describe("Algorand Standard Assets", function () { }); it("should revoke if asset is frozen", () => { - const freezeParam: FreezeAssetParam = { - type: TransactionType.FreezeAsset, - sign: SignType.SecretKey, + const freezeParam: types.FreezeAssetParam = { + type: types.TransactionType.FreezeAsset, + sign: types.SignType.SecretKey, fromAccount: elon.account, assetID: assetId, freezeTarget: bob.address, freezeState: true, payFlags: {} }; - const revokeParam: RevokeAssetParam = { - type: TransactionType.RevokeAsset, - sign: SignType.SecretKey, + const revokeParam: types.RevokeAssetParam = { + type: types.TransactionType.RevokeAsset, + sign: types.SignType.SecretKey, fromAccount: elon.account, recipient: john.address, assetID: assetId, @@ -575,9 +574,9 @@ describe("Algorand Standard Assets", function () { }); it("Should fail because only manager can destroy assets", () => { - const destroyParam: DestroyAssetParam = { - type: TransactionType.DestroyAsset, - sign: SignType.SecretKey, + const destroyParam: types.DestroyAssetParam = { + type: types.TransactionType.DestroyAsset, + sign: types.SignType.SecretKey, fromAccount: alice.account, assetID: assetId, payFlags: {} @@ -590,9 +589,9 @@ describe("Algorand Standard Assets", function () { it("Should destroy asset", () => { const initialCreatorMinBalance = john.minBalance; - const destroyParam: DestroyAssetParam = { - type: TransactionType.DestroyAsset, - sign: SignType.SecretKey, + const destroyParam: types.DestroyAssetParam = { + type: types.TransactionType.DestroyAsset, + sign: types.SignType.SecretKey, fromAccount: elon.account, assetID: assetId, payFlags: {} @@ -610,9 +609,9 @@ describe("Algorand Standard Assets", function () { }); it("Should not destroy asset if total assets are not in creator's account", () => { - const destroyParam: DestroyAssetParam = { - type: TransactionType.DestroyAsset, - sign: SignType.SecretKey, + const destroyParam: types.DestroyAssetParam = { + type: types.TransactionType.DestroyAsset, + sign: types.SignType.SecretKey, fromAccount: elon.account, assetID: assetId, payFlags: {} diff --git a/packages/web/.eslintignore b/packages/web/.eslintignore new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/packages/web/.eslintignore @@ -0,0 +1 @@ + diff --git a/packages/web/.eslintrc.js b/packages/web/.eslintrc.js new file mode 100644 index 000000000..79a284c3f --- /dev/null +++ b/packages/web/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + extends: [ + "../../.eslintrc.js" + ], + parserOptions: { + project: "./test/tsconfig.json" + } +} diff --git a/packages/web/.mocharc.json b/packages/web/.mocharc.json new file mode 100644 index 000000000..7e7338e3e --- /dev/null +++ b/packages/web/.mocharc.json @@ -0,0 +1,14 @@ +{ + "diff": true, + "extension": ["js", "ts"], + "package": "./package.json", + "reporter": "spec", + "slow": 75, + "timeout": 10000, + "ui": "bdd", + "watch-files": ["src/**/*.js", "test/**/*.js", "src/**/*.ts", "test/**/*.ts"], + "require": ["ts-node/register", "source-map-support/register"], + "recursive": true, + "ignore": ["test/fixture-projects/**/*"], + "file": "../../test/setup.js" +} diff --git a/packages/web/LICENSE b/packages/web/LICENSE new file mode 100644 index 000000000..c4c80449b --- /dev/null +++ b/packages/web/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Robert Zaremba and Algo Builder contributors (see package.json) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/web/README.md b/packages/web/README.md new file mode 100644 index 000000000..f27e17cf3 --- /dev/null +++ b/packages/web/README.md @@ -0,0 +1 @@ +# Algob Web diff --git a/packages/web/package.json b/packages/web/package.json new file mode 100644 index 000000000..b78c36b38 --- /dev/null +++ b/packages/web/package.json @@ -0,0 +1,75 @@ +{ + "name": "@algo-builder/web", + "version": "0.0.1", + "license": "Apache-2.0", + "repository": "https://github.com/scale-it/algo-builder.git", + "description": "package for the web", + "keywords": [ + "smart-contracts", + "blockchain", + "algorand", + "dapps", + "javascript", + "tooling" + ], + "main": "build/index.js", + "types": "build/index.d.ts", + "engines": { + "node": ">=14.11.0" + }, + "scripts": { + "lint": "eslint --ext .js,.ts src", + "lint:fix": "eslint --fix --ext .js,.ts src", + "lint:unix": "eslint --format unix --ext .js,.ts src", + "test": "mocha", + "coverage": "nyc ../../node_modules/mocha/bin/mocha", + "build": "tsc --build .", + "build:watch": "tsc -w -p .", + "prepublish": "yarn build", + "publish": "yarn publish --access public" + }, + "files": [ + "build/", + "LICENSE", + "README.md" + ], + "devDependencies": { + "@types/chai": "^4.2.12", + "@types/glob": "^7.1.2", + "@types/murmurhash": "0.0.1", + "@types/sinon": "^9.0.4", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nyc": "^15.1.0", + "sinon": "^9.0.2" + }, + "dependencies": { + "@types/lodash.clonedeep": "^4.5.6", + "algosdk": "^1.9.1", + "glob": "^7.1.6", + "js-sha256": "^0.9.0", + "js-sha512": "^0.8.0", + "lodash.clonedeep": "^4.5.0", + "murmurhash": "^1.0.0", + "sha3": "^2.1.3", + "source-map-support": "^0.5.19", + "tweetnacl-ts": "^1.0.3", + "types": "^0.1.0" + }, + "nyc": { + "extension": [ + ".ts" + ], + "exclude": [ + "build", + "test", + "coverage", + ".nyc_output" + ], + "reporter": [ + "text", + "lcovonly" + ], + "all": true + } +} diff --git a/packages/algob/src/errors/errors-list.ts b/packages/web/src/errors/errors-list.ts similarity index 98% rename from packages/algob/src/errors/errors-list.ts rename to packages/web/src/errors/errors-list.ts index b7b919aba..71895fe88 100644 --- a/packages/algob/src/errors/errors-list.ts +++ b/packages/web/src/errors/errors-list.ts @@ -161,6 +161,22 @@ Please check algob output for more details.` message: "App %app% is already deleted from network", title: "App deleted", description: `app already deleted error` + }, + TRANSACTION_TYPE_ERROR: { + number: 16, + message: "Error. Transaction Type %transaction% is Unknown", + title: "Unknown Transaction type", + description: `Provided transaction type is unknown + Please double check your transaction type` + }, + PARAM_PARSE_ERROR: { + number: 17, + message: `Invalid ASA definition: '%source%'. + Reason: %reason%`, + title: "Invalid ASA definition", + description: `Invalid ASA definition: '%source%'. + Reason: %reason% + Please check your ASA file` } }; diff --git a/packages/algob/src/errors/errors.ts b/packages/web/src/errors/errors.ts similarity index 65% rename from packages/algob/src/errors/errors.ts rename to packages/web/src/errors/errors.ts index 398731445..2fdc68f9b 100644 --- a/packages/algob/src/errors/errors.ts +++ b/packages/web/src/errors/errors.ts @@ -1,8 +1,7 @@ -import { applyErrorMessageTemplate } from "@algo-builder/runtime"; import type { RequestError } from 'algosdk'; -import { getClosestCallerPackage } from "../internal/util/caller-package"; import type { AnyMap } from "../types"; +import { getClosestCallerPackage } from "../util/caller-package"; import { ErrorDescriptor, ERRORS, getErrorCode } from "./errors-list"; export { ERRORS }; // re-export errors-list @@ -122,3 +121,69 @@ export function parseAlgorandError (e: RequestError, ctx: AnyMap): Error { } return e; } + +/** + * This function applies error messages templates like this: + * + * - Template is a string which contains a variable tags. A variable tag is a + * a variable name surrounded by %. Eg: %plugin1% + * - A variable name is a string of alphanumeric ascii characters. + * - Every variable tag is replaced by its value. + * - %% is replaced by %. + * - Values can't contain variable tags. + * - If a variable is not present in the template, but present in the values + * object, an error is thrown. + * + * @param template The template string. + * @param values A map of variable names to their values. + */ +export function applyErrorMessageTemplate ( + template: string, + values: { [templateVar: string]: any } // eslint-disable-line @typescript-eslint/no-explicit-any +): string { + return _applyErrorMessageTemplate(template, values); +} + +function _applyErrorMessageTemplate ( + template: string, + values: { [templateVar: string]: any } // eslint-disable-line @typescript-eslint/no-explicit-any +): string { + if (template.includes("%%")) { + return template + .split("%%") + .map((part) => _applyErrorMessageTemplate(part, values)) + .join("%"); + } + + for (const variableName of Object.keys(values)) { + let value: string; + + if (values[variableName] === undefined) { + value = "undefined"; + } else if (values[variableName] === null) { + value = "null"; + } else { + value = values[variableName].toString(); + } + + if (value === undefined) { + value = "undefined"; + } + + const variableTag = `%${variableName}%`; + template = replaceAll(template, variableTag, value); + } + + return template; +} + +/** + * Replaces all the instances of [[toReplace]] by [[replacement]] in [[str]]. + */ +export function replaceAll ( + str: string, + toReplace: string, + replacement: string +): string { + return str.split(toReplace).join(replacement); +} diff --git a/packages/web/src/index.ts b/packages/web/src/index.ts new file mode 100644 index 000000000..0e4f4f818 --- /dev/null +++ b/packages/web/src/index.ts @@ -0,0 +1,10 @@ +export * as types from "./types"; +export * as parsing from "./lib/parsing"; +export * as tx from "./lib/txn"; +export { ASADefSchema, ASADefsSchema } from "./types-input"; +export { + BuilderError, BuilderPluginError, + applyErrorMessageTemplate, parseAlgorandError +} from "./errors/errors"; +export { ERRORS, ErrorDescriptor, ERROR_RANGES } from "./errors/errors-list"; +export { getClosestCallerPackage } from "./util/caller-package"; diff --git a/packages/web/src/lib/constants.ts b/packages/web/src/lib/constants.ts new file mode 100644 index 000000000..4f3c78882 --- /dev/null +++ b/packages/web/src/lib/constants.ts @@ -0,0 +1,3 @@ +export const MIN_UINT64 = 0n; +export const MAX_UINT64 = 0xFFFFFFFFFFFFFFFFn; +export const reDigit = /^\d+$/; diff --git a/packages/web/src/lib/parsing.ts b/packages/web/src/lib/parsing.ts new file mode 100644 index 000000000..dc53ed783 --- /dev/null +++ b/packages/web/src/lib/parsing.ts @@ -0,0 +1,88 @@ +import { decodeAddress, encodeUint64 } from "algosdk"; + +import { MAX_UINT64, MIN_UINT64, reDigit } from "./constants"; + +// verify n is an unsigned 64 bit integer +function assertUint64 (n: bigint): void { + if (n < MIN_UINT64 || n > MAX_UINT64) { + throw new Error(`Invalid uint64 ${n}`); + } +} + +// parse string to Uint8Array +export function stringToBytes (s: string): Uint8Array { + return new Uint8Array(Buffer.from(s)); +} + +/** + * Converts 64 bit unsigned integer to bytes in big endian. + */ +export function uint64ToBigEndian (x: number | bigint): Uint8Array { + assertUint64(BigInt(x)); + return encodeUint64(x); +} + +/** + * Takes an Algorand address in string form and decodes it into a Uint8Array (as public key) + * @param addr : algorand address + */ +export function addressToPk (addr: string): Uint8Array { + return decodeAddress(addr).publicKey; +} + +const throwFmtError = (appArg: string): void => { + throw new Error(`Format of arguments passed to stateful smart is invalid for ${appArg}`); +}; + +/** + * Parses appArgs to bytes if arguments passed to App are similar to goal ('int:1', 'str:hello'..) + * https://developer.algorand.org/docs/features/asc1/stateful/#passing-arguments-to-stateful-smart-contracts + * eg. "int:1" => new Uint8Aarray([0, 0, 0, 0, 0, 0, 0, 1]) + * NOTE: parseAppArgs returns undefined to handle the case when application args passed to + * stateful smart contract is undefined + * @param appArgs : arguments to stateful smart contract + */ +export function parseAppArgs (appArgs?: Array): Uint8Array[] | undefined { + if (appArgs === undefined) { return undefined; } + const args = []; + + for (const appArg of appArgs) { + // if appArg already bytes, then we don't need to parse + // just push to array and continue + if (appArg instanceof Uint8Array) { + args.push(appArg); + continue; + } + const [type, value] = appArg.split(':'); // eg "int:1" => ['int', '1'] + + // if given string is not invalid, throw error + if (type === undefined || value === undefined) { throwFmtError(appArg); } + + // parse string to bytes according to type + let arg; + switch (type) { + case 'int': { + if (!reDigit.test(value)) { throwFmtError(appArg); } // verify only digits are present in string + arg = uint64ToBigEndian(BigInt(value)); + break; + } + case 'str': { + arg = stringToBytes(value); + break; + } + case 'addr': { + arg = addressToPk(value); + break; + } + case 'b64': { + arg = new Uint8Array(Buffer.from(value, 'base64')); + break; + } + default: { + throwFmtError(appArg); + } + } + args.push(arg); + }; + return args as Uint8Array[]; +} diff --git a/packages/web/src/lib/txn.ts b/packages/web/src/lib/txn.ts new file mode 100644 index 000000000..db41d4707 --- /dev/null +++ b/packages/web/src/lib/txn.ts @@ -0,0 +1,261 @@ +import algosdk, { SuggestedParams, Transaction } from 'algosdk'; + +import { BuilderError } from '../errors/errors'; +import { ERRORS } from '../errors/errors-list'; +import { AccountAddress, ExecParams, SignType, TransactionType } from "../types"; +import { parseAppArgs } from "./parsing"; + +export function encodeNote (note: string | undefined, noteb64: string| undefined): Uint8Array | undefined { + if (note === undefined && noteb64 === undefined) { return undefined; } + const encoder = new TextEncoder(); + return noteb64 ? encoder.encode(noteb64) : encoder.encode(note); +} + +/** + * Returns from address from the transaction params depending on @SignType + * @param execParams transaction execution params passed by user + */ +export function getFromAddress (execParams: ExecParams): AccountAddress { + if (execParams.sign === SignType.SecretKey) { + return execParams.fromAccountAddr ?? execParams.fromAccount.addr; + } + return execParams.fromAccountAddr; +} + +/** + * Returns unsigned transaction as per ExecParams + * ExecParams can be of following types: + * + AlgoTransferParam used for transferring algo + * + AssetTransferParam used for transferring asset + * + ModifyAssetParam used to modify asset mutable properties + * + FreezeAssetParam used to freeze asset (only permitted by asa freeze account) + * + RevokeAssetParam used to revoke assets (by asset clawback) + * + DestroyAssetParam used to delete asset (by asset manager) + * + Deploy Params - deploy ASA, deploy App + * + OptIn Params - optInToASA, optInToApp + * + AppCallsParam (NoOp, Clear, Delete..)used for calling stateful smart contracts. + For more advanced use-cases, please use `algosdk.tx` directly. + NOTE: parseAppArgs is used to handle case when user passes appArgs similar to goal + * @param execParams ExecParams + * @param suggestedParams blockchain transaction suggested parameters (firstRound, lastRound, fee..) + * @returns SDK Transaction object + */ +export function mkTransaction (execParams: ExecParams, suggestedParams: SuggestedParams): Transaction { + const note = encodeNote(execParams.payFlags.note, execParams.payFlags.noteb64); + const transactionType = execParams.type; + const fromAccountAddr = getFromAddress(execParams); + switch (execParams.type) { + case TransactionType.TransferAsset: { + return algosdk.makeAssetTransferTxnWithSuggestedParams( + fromAccountAddr, + execParams.toAccountAddr, + execParams.payFlags.closeRemainderTo, + undefined, + execParams.amount, + note, + execParams.assetID, + suggestedParams); + } + case TransactionType.ModifyAsset: { + return algosdk.makeAssetConfigTxnWithSuggestedParams( + fromAccountAddr, + encodeNote(execParams.payFlags.note, execParams.payFlags.noteb64), + execParams.assetID, + execParams.fields.manager !== "" ? execParams.fields.manager : undefined, + execParams.fields.reserve !== "" ? execParams.fields.reserve : undefined, + execParams.fields.freeze !== "" ? execParams.fields.freeze : undefined, + execParams.fields.clawback !== "" ? execParams.fields.clawback : undefined, + suggestedParams, + false + ); + } + case TransactionType.FreezeAsset: { + return algosdk.makeAssetFreezeTxnWithSuggestedParams( + fromAccountAddr, + encodeNote(execParams.payFlags.note, execParams.payFlags.noteb64), + execParams.assetID, + execParams.freezeTarget, + execParams.freezeState, + suggestedParams + ); + } + case TransactionType.RevokeAsset: { + return algosdk.makeAssetTransferTxnWithSuggestedParams( + fromAccountAddr, + execParams.recipient, + execParams.payFlags.closeRemainderTo, + execParams.revocationTarget, + execParams.amount, + encodeNote(execParams.payFlags.note, execParams.payFlags.noteb64), + execParams.assetID, + suggestedParams + ); + } + case TransactionType.DestroyAsset: { + return algosdk.makeAssetDestroyTxnWithSuggestedParams( + fromAccountAddr, + encodeNote(execParams.payFlags.note, execParams.payFlags.noteb64), + execParams.assetID, + suggestedParams + ); + } + case TransactionType.TransferAlgo: { + return algosdk.makePaymentTxnWithSuggestedParams( + fromAccountAddr, + execParams.toAccountAddr, + execParams.amountMicroAlgos, + execParams.payFlags.closeRemainderTo, + note, + suggestedParams, + execParams.payFlags.rekeyTo); + } + case TransactionType.ClearApp: { + return algosdk.makeApplicationClearStateTxn( + fromAccountAddr, + suggestedParams, + execParams.appID, + parseAppArgs(execParams.appArgs), + execParams.accounts, + execParams.foreignApps, + execParams.foreignAssets, + note, + execParams.lease, + execParams.payFlags.rekeyTo + ); + } + case TransactionType.DeleteApp: { + return algosdk.makeApplicationDeleteTxn( + fromAccountAddr, + suggestedParams, + execParams.appID, + parseAppArgs(execParams.appArgs), + execParams.accounts, + execParams.foreignApps, + execParams.foreignAssets, + note, + execParams.lease, + execParams.payFlags.rekeyTo + ); + } + case TransactionType.CallNoOpSSC: { + return algosdk.makeApplicationNoOpTxn( + fromAccountAddr, + suggestedParams, + execParams.appID, + parseAppArgs(execParams.appArgs), + execParams.accounts, + execParams.foreignApps, + execParams.foreignAssets, + note, + execParams.lease, + execParams.payFlags.rekeyTo); + } + case TransactionType.CloseApp: { + return algosdk.makeApplicationCloseOutTxn( + fromAccountAddr, + suggestedParams, + execParams.appID, + parseAppArgs(execParams.appArgs), + execParams.accounts, + execParams.foreignApps, + execParams.foreignAssets, + note, + execParams.lease, + execParams.payFlags.rekeyTo + ); + } + case TransactionType.DeployASA: { + if (execParams.asaDef) { + // https://github.com/algorand/docs/blob/master/examples/assets/v2/javascript/AssetExample.js#L104 + return algosdk.makeAssetCreateTxnWithSuggestedParams( + fromAccountAddr, + note, + BigInt(execParams.asaDef.total ?? 0), + execParams.asaDef.decimals, + execParams.asaDef.defaultFrozen, + execParams.asaDef.manager, + execParams.asaDef.reserve, + execParams.asaDef.freeze, + execParams.asaDef.clawback, + execParams.asaDef.unitName, + execParams.asaName, + execParams.asaDef.url, + execParams.asaDef.metadataHash, + suggestedParams + ); + } else { + throw new BuilderError( + ERRORS.GENERAL.PARAM_PARSE_ERROR, { + reason: "ASA Definition not found", + source: execParams.asaName + }); + } + } + case TransactionType.DeployApp: { + const onComplete = algosdk.OnApplicationComplete.NoOpOC; + + return algosdk.makeApplicationCreateTxn( + fromAccountAddr, + suggestedParams, + onComplete, + execParams.approvalProg, + execParams.clearProg, + execParams.localInts, + execParams.localBytes, + execParams.globalInts, + execParams.globalBytes, + parseAppArgs(execParams.appArgs), + execParams.accounts, + execParams.foreignApps, + execParams.foreignAssets, + note, + execParams.lease, + execParams.payFlags.rekeyTo + ); + } + case TransactionType.UpdateApp: { + return algosdk.makeApplicationUpdateTxn( + fromAccountAddr, + suggestedParams, + execParams.appID, + execParams.approvalProg, + execParams.clearProg, + parseAppArgs(execParams.appArgs), + execParams.accounts, + execParams.foreignApps, + execParams.foreignAssets, + note, + execParams.lease, + execParams.payFlags.rekeyTo); + } + case TransactionType.OptInToApp: { + return algosdk.makeApplicationOptInTxn( + fromAccountAddr, + suggestedParams, + execParams.appID, + parseAppArgs(execParams.appArgs), + execParams.accounts, + execParams.foreignApps, + execParams.foreignAssets, + note, + execParams.lease, + execParams.payFlags.rekeyTo); + } + case TransactionType.OptInASA: { + return algosdk.makeAssetTransferTxnWithSuggestedParams( + fromAccountAddr, + fromAccountAddr, + undefined, + undefined, + 0, + note, + execParams.assetID, + suggestedParams + ); + } + default: { + throw new BuilderError(ERRORS.GENERAL.TRANSACTION_TYPE_ERROR, + { transaction: transactionType }); + } + } +} diff --git a/packages/web/src/lib/web-mode.ts b/packages/web/src/lib/web-mode.ts new file mode 100644 index 000000000..0bda77162 --- /dev/null +++ b/packages/web/src/lib/web-mode.ts @@ -0,0 +1,133 @@ +import algosdk, { ConfirmedTxInfo, SuggestedParams, Transaction } from "algosdk"; + +import { AlgoSigner, AlgoSignerSendTx, AlgoSignerSignedTx, AlgoSignerToBeSignedTx, ExecParams, TxParams } from "../types"; +import { mkTransaction } from "./txn"; + +const CONFIRMED_ROUND = "confirmed-round"; +const LAST_ROUND = "last-round"; + +export class WebMode { + algoSigner: AlgoSigner; + chainName: string; + + constructor (algoSigner: AlgoSigner, chainName: string) { + this.algoSigner = algoSigner; + this.chainName = chainName; + } + + /** + * wait for confirmation for transaction using transaction id + * @param txId Transaction id + */ + async waitForConfirmation (txId: string): Promise { + const response = await this.algoSigner.algod({ + ledger: this.chainName, + path: '/v2/status' + }); + console.log(response); + let lastround = response[LAST_ROUND]; + while (true) { + const pendingInfo = await this.algoSigner.algod({ + ledger: this.chainName, + path: `/v2/transactions/pending/${txId}` + }); + if ( + pendingInfo[CONFIRMED_ROUND] !== null && + pendingInfo[CONFIRMED_ROUND] > 0 + ) { + return pendingInfo; + } + lastround++; + await this.algoSigner.algod({ + ledger: this.chainName, + path: `/v2/status/wait-for-block-after/${lastround}`// eslint-disable-line @typescript-eslint/restrict-template-expressions + }); + } + } + + /** + * Sender transaction to network + * @param signedTxn signed transaction + */ + async sendTransaction (signedTxn: any): Promise { + return this.algoSigner.send({ + ledger: this.chainName, + tx: signedTxn.blob + }); + } + + /** + * Sign transaction using algosigner + * @param txns Array of transactions in base64 + */ + async signTransaction (txns: AlgoSignerToBeSignedTx[]): Promise { + return this.algoSigner.signTxn(txns); + } + + /** + * Returns suggested transaction parameters using algosigner + * @param userParams Transaction parameters + */ + async getSuggestedParams (userParams: TxParams): Promise { + const txParams = await this.algoSigner.algod({ + ledger: this.chainName, + path: '/v2/transactions/params' + }); + const s: SuggestedParams = { + fee: txParams.fee, + genesisHash: txParams["genesis-hash"], + genesisID: txParams["genesis-id"], + firstRound: txParams[LAST_ROUND], + lastRound: Number(txParams[LAST_ROUND]) + 1000, + flatFee: false + }; + + s.flatFee = userParams.totalFee !== undefined; + s.fee = userParams.totalFee ?? userParams.feePerByte ?? txParams["min-fee"]; + if (s.flatFee) s.fee = Math.max(s.fee, txParams["min-fee"]); + + s.firstRound = userParams.firstValid ?? s.firstRound; + s.lastRound = userParams.firstValid === undefined || userParams.validRounds === undefined + ? s.lastRound + : Number(userParams.firstValid) + Number(userParams.validRounds); + + return s; + } + + /** + * Execute single transaction or group of transactions (atomic transaction) + * @param execParams transaction parameters or atomic transaction parameters + */ + async executeTransaction (execParams: ExecParams | ExecParams[]): + Promise { + let signedTxn; + let txns: Transaction[] = []; + if (Array.isArray(execParams)) { + if (execParams.length > 16) { throw new Error("Maximum size of an atomic transfer group is 16"); } + + for (const [idx, txn] of execParams.entries()) { + txns.push(await mkTransaction(txn, await this.getSuggestedParams(txn.payFlags))); + } + + txns = algosdk.assignGroupID(txns); + const binaryTxs = txns.map((txn: Transaction) => { + return txn.toByte(); + }); + const base64Txs = binaryTxs.map((txn: Uint8Array) => { + return this.algoSigner.encoding.msgpackToBase64(txn); + }); + const toBeSignedTxns = base64Txs.map((txn: string) => { + return { txn: txn }; + }); + signedTxn = this.signTransaction(toBeSignedTxns); + } else { + const txn = await mkTransaction(execParams, await this.getSuggestedParams(execParams.payFlags)); + + const toBeSignedTxn = this.algoSigner.encoding.msgpackToBase64(txn.toByte()); + signedTxn = this.signTransaction([{ txn: toBeSignedTxn }]); + } + + const txInfo = await this.sendTransaction(signedTxn); + return await this.waitForConfirmation(txInfo.txId); + } +} diff --git a/packages/runtime/src/types-input.ts b/packages/web/src/types-input.ts similarity index 100% rename from packages/runtime/src/types-input.ts rename to packages/web/src/types-input.ts diff --git a/packages/web/src/types.ts b/packages/web/src/types.ts new file mode 100644 index 000000000..14157dd4d --- /dev/null +++ b/packages/web/src/types.ts @@ -0,0 +1,281 @@ +import { Account as AccountSDK, LogicSig, LogicSigArgs } from 'algosdk'; +import * as z from 'zod'; + +import type { ASADefSchema, ASADefsSchema } from "./types-input"; + +export type AccountAddress = string; + +export interface AnyMap { + [key: string]: any // eslint-disable-line @typescript-eslint/no-explicit-any +} + +/** + * After an asset has been created only the manager, + * reserve, freeze and reserve accounts can be changed. + * All other parameters are locked for the life of the asset. + */ +export interface AssetModFields { + manager?: string + reserve?: string + freeze?: string + clawback?: string +} + +/** + * Common transaction parameters (fees, note..) */ +export interface TxParams { + /** + * feePerByte or totalFee is used to set the appropriate transaction fee parameter. + * If both are set then totalFee takes precedence. + * NOTE: SDK expects`fee: number` and boolean `flatFee`. But the API expects only one + * on parameter: `fee`. Here, we define feePerByte and totalFee - both as numberic + * parameters. We think that this is more explicit. */ + feePerByte?: number + totalFee?: number + // The first round for when the transaction is valid. + firstValid?: number + // firstValid + validRounds will give us the ending round for which the transaction is valid. + validRounds?: number + // A lease enforces mutual exclusion of transactions. + lease?: Uint8Array + // Any data up to 1000 bytes. + note?: string + noteb64?: string + // When set, it indicates that the transaction is requesting + // that the Sender account should be closed, and all remaining + // funds, after the fee and amount are paid, be transferred to this address. + closeRemainderTo?: AccountAddress + // Specifies the authorized address. + rekeyTo?: AccountAddress + // you can learn more about these parameters here.(https://developer.algorand.org/docs/reference/transactions/#common-fields-header-and-type) +} + +/** + * Stateful Smart contract flags for specifying sender and schema */ +export interface AppDeploymentFlags extends AppOptionalFlags { + sender: AccountSDK + localInts: number + localBytes: number + globalInts: number + globalBytes: number +} + +/** + * Stateful smart contract transaction optional parameters (accounts, args..). */ +export interface AppOptionalFlags { + /** + * Transaction specific arguments accessed from + * the application's approval-program and clear-state-program. + */ + appArgs?: Array + /** + * List of accounts in addition to the sender that may + * be accessed from the application's approval-program and clear-state-program. + */ + accounts?: string[] + /** + * Lists the applications in addition to the application-id + * whose global states may be accessed by this + * application's approval-program and clear-state-program. The access is read-only. + */ + foreignApps?: number[] + /** + * Lists the assets whose AssetParams may be accessed by + * this application's approval-program and clear-state-program. + * The access is read-only. + */ + foreignAssets?: number[] + // Any data up to 1000 bytes. + note?: Uint8Array + // A lease enforces mutual exclusion of transactions. + lease?: Uint8Array + // you can learn more about these parameters from here.(https://developer.algorand.org/docs/reference/transactions/#application-call-transaction) +} + +/** + * Transaction execution parameters (on blockchain OR runtime) */ +export type ExecParams = AlgoTransferParam | AssetTransferParam | AppCallsParam | +ModifyAssetParam | FreezeAssetParam | RevokeAssetParam | +DestroyAssetParam | DeployASAParam | DeployAppParam | +OptInToAppParam | OptInASAParam | UpdateAppParam; + +export enum SignType { + SecretKey, + LogicSignature +} + +export enum TransactionType { + TransferAlgo, + TransferAsset, + ModifyAsset, + FreezeAsset, + RevokeAsset, + DestroyAsset, + CallNoOpSSC, + ClearApp, + CloseApp, + DeleteApp, + DeployASA, + DeployApp, + OptInASA, + OptInToApp, + UpdateApp +} + +interface SignWithSk { + sign: SignType.SecretKey + fromAccount: AccountSDK + /** + * if passed then it will be used as the from account address, but tx will be signed + * by fromAcount's sk. This is used if an account address is rekeyed to another account. */ + fromAccountAddr?: AccountAddress +} + +interface SignWithLsig { + sign: SignType.LogicSignature + fromAccountAddr: AccountAddress + lsig: LogicSig + /** stateless smart contract args */ + args?: LogicSigArgs +} + +export type Sign = SignWithSk | SignWithLsig; + +export type BasicParams = Sign & { + payFlags: TxParams +}; + +export type DeployASAParam = BasicParams & { + type: TransactionType.DeployASA + asaName: string + asaDef?: Partial +}; + +export type DeployAppParam = BasicParams & AppOptionalFlags & { + type: TransactionType.DeployApp + approvalProgram: string + clearProgram: string + localInts: number + localBytes: number + globalInts: number + globalBytes: number + approvalProg?: Uint8Array + clearProg?: Uint8Array +}; + +export type UpdateAppParam = BasicParams & AppOptionalFlags & { + type: TransactionType.UpdateApp + appID: number + newApprovalProgram: string + newClearProgram: string + approvalProg?: Uint8Array + clearProg?: Uint8Array +}; + +export type OptInToAppParam = BasicParams & AppOptionalFlags & { + type: TransactionType.OptInToApp + appID: number +}; + +export type OptInASAParam = BasicParams & { + type: TransactionType.OptInASA + assetID: number | string +}; + +export type ModifyAssetParam = BasicParams & { + type: TransactionType.ModifyAsset + assetID: number | string + fields: AssetModFields +}; + +export type FreezeAssetParam = BasicParams & { + type: TransactionType.FreezeAsset + assetID: number | string + freezeTarget: AccountAddress + freezeState: boolean +}; + +export type RevokeAssetParam = BasicParams & { + type: TransactionType.RevokeAsset + /** + * Revoked assets are sent to this address + */ + recipient: AccountAddress + assetID: number | string + /** Revocation target is the account from which the clawback revokes asset. */ + revocationTarget: AccountAddress + amount: number | bigint +}; + +export type DestroyAssetParam = BasicParams & { + type: TransactionType.DestroyAsset + assetID: number | string +}; + +export type AlgoTransferParam = BasicParams & { + type: TransactionType.TransferAlgo + toAccountAddr: AccountAddress + amountMicroAlgos: number | bigint +}; + +export type AssetTransferParam = BasicParams & { + type: TransactionType.TransferAsset + toAccountAddr: AccountAddress + amount: number | bigint + assetID: number | string +}; + +export type AppCallsParam = BasicParams & AppOptionalFlags & { + type: TransactionType.CallNoOpSSC | TransactionType.ClearApp | + TransactionType.CloseApp | TransactionType.DeleteApp + appID: number +}; + +// Algosigner types + +export interface AlgoSignerTx { + "consensus-version": string + "fee": number + "genesis-hash": string + "genesis-id": string + "last-round": number + "min-fee": number +} + +export interface AlgoSignerSignedTx { + "txID": string + "blob": string +} + +export interface AlgoSignerSendTx { + "txId": string +} + +export interface AlgoSignerToBeSignedTx { + txn: string +} + +export interface encoding { + msgpackToBase64: (txn: Uint8Array) => string + + base64ToMsgpack: (txn: string) => Uint8Array +} + +export interface AlgoSigner { + // algod, sign, send, signTxn, accounts + // Create an Algod client to get suggested transaction params + // let client = new algosdk.Algodv2(token, server, port, headers); + accounts: (param: unknown) => unknown[] + + algod: (param: unknown) => any + + signTxn: (param: unknown[]) => AlgoSignerSignedTx + + send: (param: any) => AlgoSignerSendTx + + encoding: encoding +} + +export type ASADef = z.infer; + +export type ASADefs = z.infer; diff --git a/packages/algob/src/internal/util/caller-package.ts b/packages/web/src/util/caller-package.ts similarity index 100% rename from packages/algob/src/internal/util/caller-package.ts rename to packages/web/src/util/caller-package.ts diff --git a/packages/web/test/tsconfig.json b/packages/web/test/tsconfig.json new file mode 100644 index 000000000..8ce0689a2 --- /dev/null +++ b/packages/web/test/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.json", + "include": [ + "../src", + "../../@types", + "./" + ] +} diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json new file mode 100644 index 000000000..94828781e --- /dev/null +++ b/packages/web/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./build" + }, + "include": [ + "src", + "../../@types" + ] +}