diff --git a/examples/package-lock.json b/examples/package-lock.json index 9ec113c6..297126d9 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -9,8 +9,8 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@tinymanorg/tinyman-js-sdk": "^2.0.1", - "algosdk": "^1.22.0" + "@tinymanorg/tinyman-js-sdk": "^3.1.0", + "algosdk": "^2.1.0" }, "devDependencies": { "@types/node": "^18.8.5", @@ -56,11 +56,11 @@ } }, "node_modules/@tinymanorg/tinyman-js-sdk": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@tinymanorg/tinyman-js-sdk/-/tinyman-js-sdk-2.0.5.tgz", - "integrity": "sha512-8juQVqTYu0Ov9guPuSYL+Uy1YGwtvtROxItUwf9Un8XsYdjT1BZEM7C9H4YvKWgoi1sFtFM1zg5h9raJBj14yw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@tinymanorg/tinyman-js-sdk/-/tinyman-js-sdk-3.1.0.tgz", + "integrity": "sha512-l3eAuweqcqiOezmVrgTLTArCxcW251D9EPunEvdbZVYdvRKgX8NfHJFdzM1dTILMFdum6k4XSrqmUEU/+0cb5Q==", "dependencies": { - "algosdk": "^1.20.0", + "algosdk": "^2.1.0", "base64-js": "^1.5.1" } }, @@ -124,13 +124,12 @@ } }, "node_modules/algosdk": { - "version": "1.24.1", - "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.24.1.tgz", - "integrity": "sha512-9moZxdqeJ6GdE4N6fA/GlUP4LrbLZMYcYkt141J4Ss68OfEgH9qW0wBuZ3ZOKEx/xjc5bg7mLP2Gjg7nwrkmww==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-2.7.0.tgz", + "integrity": "sha512-sBE9lpV7bup3rZ+q2j3JQaFAE9JwZvjWKX00vPlG8e9txctXbgLL56jZhSWZndqhDI9oI+0P4NldkuQIWdrUyg==", "dependencies": { "algo-msgpack-with-bigint": "^2.1.1", - "buffer": "^6.0.2", - "cross-fetch": "^3.1.5", + "buffer": "^6.0.3", "hi-base32": "^0.5.1", "js-sha256": "^0.9.0", "js-sha3": "^0.8.0", @@ -140,7 +139,7 @@ "vlq": "^2.0.4" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } }, "node_modules/arg": { @@ -205,14 +204,6 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "dependencies": { - "node-fetch": "2.6.7" - } - }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -275,30 +266,6 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -371,20 +338,6 @@ "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==" }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -428,11 +381,11 @@ } }, "@tinymanorg/tinyman-js-sdk": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@tinymanorg/tinyman-js-sdk/-/tinyman-js-sdk-2.0.5.tgz", - "integrity": "sha512-8juQVqTYu0Ov9guPuSYL+Uy1YGwtvtROxItUwf9Un8XsYdjT1BZEM7C9H4YvKWgoi1sFtFM1zg5h9raJBj14yw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@tinymanorg/tinyman-js-sdk/-/tinyman-js-sdk-3.1.0.tgz", + "integrity": "sha512-l3eAuweqcqiOezmVrgTLTArCxcW251D9EPunEvdbZVYdvRKgX8NfHJFdzM1dTILMFdum6k4XSrqmUEU/+0cb5Q==", "requires": { - "algosdk": "^1.20.0", + "algosdk": "^2.1.0", "base64-js": "^1.5.1" } }, @@ -484,13 +437,12 @@ "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==" }, "algosdk": { - "version": "1.24.1", - "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.24.1.tgz", - "integrity": "sha512-9moZxdqeJ6GdE4N6fA/GlUP4LrbLZMYcYkt141J4Ss68OfEgH9qW0wBuZ3ZOKEx/xjc5bg7mLP2Gjg7nwrkmww==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-2.7.0.tgz", + "integrity": "sha512-sBE9lpV7bup3rZ+q2j3JQaFAE9JwZvjWKX00vPlG8e9txctXbgLL56jZhSWZndqhDI9oI+0P4NldkuQIWdrUyg==", "requires": { "algo-msgpack-with-bigint": "^2.1.1", - "buffer": "^6.0.2", - "cross-fetch": "^3.1.5", + "buffer": "^6.0.3", "hi-base32": "^0.5.1", "js-sha256": "^0.9.0", "js-sha3": "^0.8.0", @@ -531,14 +483,6 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "requires": { - "node-fetch": "2.6.7" - } - }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -584,19 +528,6 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -640,20 +571,6 @@ "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==" }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/examples/package.json b/examples/package.json index 19164de8..47b2ed19 100644 --- a/examples/package.json +++ b/examples/package.json @@ -9,8 +9,8 @@ "author": "Tinyman Core Team", "license": "ISC", "dependencies": { - "algosdk": "^1.22.0", - "@tinymanorg/tinyman-js-sdk": "^2.0.1" + "algosdk": "^2.1.0", + "@tinymanorg/tinyman-js-sdk": "^3.1.0" }, "devDependencies": { "@types/node": "^18.8.5", diff --git a/examples/src/index.ts b/examples/src/index.ts index fca3a4c7..aec8ce89 100644 --- a/examples/src/index.ts +++ b/examples/src/index.ts @@ -1,13 +1,16 @@ +import {PoolStatus, poolUtils} from "@tinymanorg/tinyman-js-sdk"; + import {addFlexibleLiquidity} from "./operation/add-liquidity/addFlexibleLiquidity"; import {addInitialLiquidity} from "./operation/add-liquidity/addInitialLiquidity"; import {addSingleAssetLiquidity} from "./operation/add-liquidity/addSingleAssetLiquidity"; import {bootstrapPool} from "./operation/bootstrap/bootstrapPool"; import {removeLiquidity} from "./operation/remove-liquidity/removeLiquidity"; import {removeLiquidityWithSingleAssetOut} from "./operation/remove-liquidity/removeLiquidityWithSingleAssetOut"; -import {fixedInputSwap} from "./operation/swap/fixedInputSwap"; -import {fixedOutputSwap} from "./operation/swap/fixedOutputSwap"; +import {fixedInputSwap, fixedInputSwapWithoutSwapRouter} from "./operation/swap/fixedInputSwap"; +import {fixedOutputSwap, fixedOutputSwapWithoutSwapRouter} from "./operation/swap/fixedOutputSwap"; import {getAccount} from "./util/account"; import {getAssetParams} from "./util/asset"; +import {algodClient} from "./util/client"; /** * Will run all the operations in the order they are defined @@ -19,11 +22,24 @@ async function main() { const account = await getAccount(); const {asset_1, asset_2} = await getAssetParams(); + // Comment the next line if you already bootstrapped the pool // Create the pool with the owned assets // await bootstrapPool({ account, asset_1, asset_2 }); // Add some initial liquidity to the pool - await addInitialLiquidity({account, asset_1, asset_2}); + const [_v1PoolInfo, v2PoolInfo] = await poolUtils.getPoolsForPair({ + client: algodClient, + asset1ID: Number(asset_1.id), + asset2ID: Number(asset_2.id), + network: "testnet" + }); + + if (v2PoolInfo.status === PoolStatus.NOT_CREATED) { + // Create the pool with the owned assets + await bootstrapPool({account, asset_1, asset_2}); + // Add some initial liquidity to the pool + await addInitialLiquidity({account, asset_1, asset_2}); + } // Add subsequent liquidity to the pool using the flexible mode await addFlexibleLiquidity({account, asset_1, asset_2}); @@ -40,9 +56,15 @@ async function main() { // Swap assets with fixed input await fixedInputSwap({account, asset_1, asset_2}); + // Swap assets with fixed input without using the swap router + await fixedInputSwapWithoutSwapRouter({account, asset_1, asset_2}); + // Swap assets with fixed output await fixedOutputSwap({account, asset_1, asset_2}); + // Swap assets with fixed output without using the swap router + await fixedOutputSwapWithoutSwapRouter({account, asset_1, asset_2}); + console.log("✅ All operations completed successfully"); } diff --git a/examples/src/operation/bootstrap/bootstrapPool.ts b/examples/src/operation/bootstrap/bootstrapPool.ts index e6d86656..ce7d1a80 100644 --- a/examples/src/operation/bootstrap/bootstrapPool.ts +++ b/examples/src/operation/bootstrap/bootstrapPool.ts @@ -54,7 +54,7 @@ export async function bootstrapPool({ console.log(`✅ Pool address: ${poolAddress}`); console.log(`✅ Pool token ID: ${bootstrapExecutionResponse.poolTokenID}`); console.log( - "✅ See pool account on AlgoExplorer: " + - `https://testnet.algoexplorer.io/address/${poolAddress}` + "✅ See pool account on PeraExplorer: " + + `https://testnet-api.algonode.cloud/v2/accounts/${poolAddress}` ); } diff --git a/examples/src/operation/swap/fixedInputSwap.ts b/examples/src/operation/swap/fixedInputSwap.ts index c3703761..101eeb7f 100644 --- a/examples/src/operation/swap/fixedInputSwap.ts +++ b/examples/src/operation/swap/fixedInputSwap.ts @@ -30,29 +30,24 @@ export async function fixedInputSwap({ * Swap.getQuote method, which will return the best quote (highest rate) * after checking both v1 and v2 */ - const fixedInputSwapQuote = Swap.v2.getQuote( - SwapType.FixedInput, + + const fixedInputSwapQuote = await Swap.v2.getQuote({ + type: SwapType.FixedInput, pool, - {id: pool.asset1ID, amount: 1_000_000}, - {assetIn: 6, assetOut: 6} - ); - const assetIn = { - id: fixedInputSwapQuote.assetInID, - amount: fixedInputSwapQuote.assetInAmount - }; - const assetOut = { - id: fixedInputSwapQuote.assetOutID, - amount: fixedInputSwapQuote.assetOutAmount - }; + amount: 1_000_000, + assetIn: {id: pool.asset1ID, decimals: 6}, + assetOut: {id: pool.asset2ID, decimals: 6}, + isSwapRouterEnabled: true, + network: "testnet" + }); const fixedInputSwapTxns = await Swap.v2.generateTxns({ client: algodClient, + network: "testnet", + quote: fixedInputSwapQuote, swapType: SwapType.FixedInput, - pool, + slippage: 0.05, initiatorAddr, - assetIn, - assetOut, - slippage: 0.05 }); const signedTxns = await Swap.v2.signTxns({ @@ -61,14 +56,74 @@ export async function fixedInputSwap({ }); const swapExecutionResponse = await Swap.v2.execute({ - network: "testnet" as SupportedNetwork, + quote: fixedInputSwapQuote, client: algodClient, signedTxns, + txGroup: fixedInputSwapTxns + }); + + console.log("✅ Fixed Input Swap executed successfully!"); + console.log({txnID: swapExecutionResponse.txnID}); +} + +/** + * Executes a swap with a fixed input amount + * (Input amount is entered by the user, output amount is to be calculated by the SDK) + */ +export async function fixedInputSwapWithoutSwapRouter({ + account, + asset_1, + asset_2 +}: { + account: Account; + asset_1: {id: string; unit_name: string}; + asset_2: {id: string; unit_name: string}; +}) { + const initiatorAddr = account.addr; + const pool = await poolUtils.v2.getPoolInfo({ + network: "testnet" as SupportedNetwork, + client: algodClient, + asset1ID: Number(asset_1.id), + asset2ID: Number(asset_2.id) + }); + + /** + * This example uses only v2 quote. Similarly, we can use + * Swap.getQuote method, which will return the best quote (highest rate) + * after checking both v1 and v2, without using the swap router + */ + + const fixedInputSwapQuote = await Swap.v2.getQuote({ + type: SwapType.FixedInput, pool, + amount: 1_000_000, + assetIn: {id: pool.asset1ID, decimals: 6}, + assetOut: {id: pool.asset2ID, decimals: 6}, + isSwapRouterEnabled: false, + network: "testnet" + }); + + const fixedInputSwapTxns = await Swap.v2.generateTxns({ + client: algodClient, + network: "testnet", + quote: fixedInputSwapQuote, + swapType: SwapType.FixedInput, + slippage: 0.05, + initiatorAddr, + }); + + const signedTxns = await Swap.v2.signTxns({ txGroup: fixedInputSwapTxns, - assetIn + initiatorSigner: signerWithSecretKey(account) }); - console.log("✅ Fixed Input Swap executed successfully!"); + const swapExecutionResponse = await Swap.v2.execute({ + quote: fixedInputSwapQuote, + client: algodClient, + signedTxns, + txGroup: fixedInputSwapTxns + }); + + console.log("✅ Fixed Input Swap with disabled Swap Router executed successfully!"); console.log({txnID: swapExecutionResponse.txnID}); } diff --git a/examples/src/operation/swap/fixedOutputSwap.ts b/examples/src/operation/swap/fixedOutputSwap.ts index eb673561..1960ad99 100644 --- a/examples/src/operation/swap/fixedOutputSwap.ts +++ b/examples/src/operation/swap/fixedOutputSwap.ts @@ -30,44 +30,88 @@ export async function fixedOutputSwap({ * Swap.getQuote method, which will return the best quote (highest rate) * after checking both v1 and v2 */ - const fixedOutputSwapQuote = Swap.v2.getQuote( - SwapType.FixedOutput, + const fixedOutputSwapQuote = await Swap.v2.getQuote({ + type: SwapType.FixedOutput, pool, - {id: pool.asset2ID, amount: 1_000_000}, - {assetIn: 6, assetOut: 6} - ); - - const assetIn = { - id: fixedOutputSwapQuote.assetInID, - amount: fixedOutputSwapQuote.assetInAmount - }; - const assetOut = { - id: fixedOutputSwapQuote.assetOutID, - amount: fixedOutputSwapQuote.assetOutAmount - }; + amount: 1_000_000, + assetIn: {id: pool.asset1ID, decimals: 6}, + assetOut: {id: pool.asset2ID, decimals: 6}, + isSwapRouterEnabled: true, + network: "testnet" + }); const fixedOutputSwapTxns = await Swap.v2.generateTxns({ client: algodClient, + network: "testnet", + quote: fixedOutputSwapQuote, swapType: SwapType.FixedOutput, - pool, + slippage: 0.05, initiatorAddr, - assetIn, - assetOut, - slippage: 0.05 }); const signedTxns = await Swap.v2.signTxns({ txGroup: fixedOutputSwapTxns, initiatorSigner: signerWithSecretKey(account) }); const swapExecutionResponse = await Swap.v2.execute({ - network: "testnet" as SupportedNetwork, + quote: fixedOutputSwapQuote!, client: algodClient, signedTxns, txGroup: fixedOutputSwapTxns, - pool, - assetIn }); console.log("✅ Fixed Output Swap executed successfully!"); console.log({txnID: swapExecutionResponse.txnID}); } + +/** + * Executes a swap with a fixed output amount without using the swap router + */ +export async function fixedOutputSwapWithoutSwapRouter({ + account, + asset_1, + asset_2 +}: { + account: Account; + asset_1: {id: string; unit_name: string}; + asset_2: {id: string; unit_name: string}; +}) { + const initiatorAddr = account.addr; + const pool = await poolUtils.v2.getPoolInfo({ + network: "testnet" as SupportedNetwork, + client: algodClient, + asset1ID: Number(asset_1.id), + asset2ID: Number(asset_2.id) + }); + + const fixedOutputSwapQuote = await Swap.v2.getQuote({ + type: SwapType.FixedOutput, + pool, + amount: 1_000_000, + assetIn: {id: pool.asset1ID, decimals: 6}, + assetOut: {id: pool.asset2ID, decimals: 6}, + isSwapRouterEnabled: false, + network: "testnet" + }); + + const fixedOutputSwapTxns = await Swap.v2.generateTxns({ + client: algodClient, + network: "testnet", + quote: fixedOutputSwapQuote, + swapType: SwapType.FixedOutput, + slippage: 0.05, + initiatorAddr, + }); + const signedTxns = await Swap.v2.signTxns({ + txGroup: fixedOutputSwapTxns, + initiatorSigner: signerWithSecretKey(account) + }); + const swapExecutionResponse = await Swap.v2.execute({ + quote: fixedOutputSwapQuote!, + client: algodClient, + signedTxns, + txGroup: fixedOutputSwapTxns, + }); + + console.log("✅ Fixed Output Swap with disabled Swap Router executed successfully!"); + console.log({txnID: swapExecutionResponse.txnID}); +} \ No newline at end of file diff --git a/examples/src/util/account.ts b/examples/src/util/account.ts index a761a080..e3abc41a 100644 --- a/examples/src/util/account.ts +++ b/examples/src/util/account.ts @@ -1,6 +1,7 @@ import { Account, generateAccount } from "algosdk"; import { writeFileSync, readFileSync } from "fs"; import { getAccountInformation } from "@tinymanorg/tinyman-js-sdk"; + import { algodClient } from "./client"; import { assertAccountHasBalance } from "./other"; @@ -15,8 +16,8 @@ export async function getAccount(): Promise { if (!account) { account = generateAccount(); - console.log("✅ Account generated: " + account.addr); - console.log("✅ Account data saved to: " + ACCOUNT_FILENAME); + console.log(`✅ Account generated: ${ account.addr}`); + console.log(`✅ Account data saved to: ${ ACCOUNT_FILENAME}`); writeFileSync(ACCOUNT_FILENAME, JSON.stringify(account)); } diff --git a/examples/src/util/client.ts b/examples/src/util/client.ts index 26ca2fbf..655d6017 100644 --- a/examples/src/util/client.ts +++ b/examples/src/util/client.ts @@ -5,6 +5,6 @@ console.log( ); export const algodClient = new algosdk.Algodv2( "", - "https://node.testnet.algoexplorerapi.io/", + "https://testnet-api.algonode.cloud", "" ); diff --git a/examples/src/util/other.ts b/examples/src/util/other.ts index 81cc6000..e1d44dd5 100644 --- a/examples/src/util/other.ts +++ b/examples/src/util/other.ts @@ -5,6 +5,7 @@ import { algodClient } from "./client"; */ export async function assertAccountHasBalance(address: string) { const accountInfo = await algodClient.accountInformation(address).do(); + if (!accountInfo["amount"]) { throw new Error( `Go to https://bank.testnet.algorand.network/?account=${address} and fund your account.`