{"id":21616383,"url":"https://github.com/rootsoft/algorand-dart","last_synced_at":"2025-04-11T07:33:48.199Z","repository":{"id":44359738,"uuid":"346495411","full_name":"RootSoft/algorand-dart","owner":"RootSoft","description":"Unofficial community SDK to interact with the Algorand network, for Dart \u0026 Flutter","archived":false,"fork":false,"pushed_at":"2024-02-04T08:19:04.000Z","size":625,"stargazers_count":36,"open_issues_count":8,"forks_count":18,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-25T05:07:21.598Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RootSoft.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-10T21:21:46.000Z","updated_at":"2024-02-06T06:54:08.000Z","dependencies_parsed_at":"2024-06-20T23:35:23.307Z","dependency_job_id":null,"html_url":"https://github.com/RootSoft/algorand-dart","commit_stats":{"total_commits":219,"total_committers":4,"mean_commits":54.75,"dds":0.3926940639269406,"last_synced_commit":"7ae5809deb5f53f853d025983461f2c338b75b3c"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RootSoft%2Falgorand-dart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RootSoft%2Falgorand-dart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RootSoft%2Falgorand-dart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RootSoft%2Falgorand-dart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RootSoft","download_url":"https://codeload.github.com/RootSoft/algorand-dart/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248358926,"owners_count":21090448,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-24T22:14:21.420Z","updated_at":"2025-04-11T07:33:48.177Z","avatar_url":"https://github.com/RootSoft.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e \n\u003cimg src=\"https://miro.medium.com/max/700/1*BFpFCJepifaREIg7qLSLag.jpeg\"\u003e\n\u003c/p\u003e\n\n# algorand-dart\n[![pub.dev][pub-dev-shield]][pub-dev-url]\n[![Effective Dart][effective-dart-shield]][effective-dart-url]\n[![Stars][stars-shield]][stars-url]\n[![Issues][issues-shield]][issues-url]\n[![MIT License][license-shield]][license-url]\n\nAlgorand is a public blockchain and protocol that aims to deliver decentralization, scale and security for all participants.\nTheir PURE PROOF OF STAKE™ consensus mechanism ensures full participation, protection, and speed within a truly decentralized network. With blocks finalized in seconds, Algorand’s transaction throughput is on par with large payment and financial networks. And Algorand is the first blockchain to provide immediate transaction finality. No forking. No uncertainty.\n\n## Introduction\nAlgorand-dart is a community SDK with an elegant approach to connect your Dart \u0026 Flutter applications to the Algorand blockchain, send transactions, create assets and query the indexer with just a few lines of code.\n\nOnce installed, you can simply connect your application to the blockchain and start sending payments\n\n```dart\nalgorand.sendPayment(\n    account: account,\n    recipient: newAccount.address,\n    amount: Algo.toMicroAlgos(5),\n);\n```\n\nor create a new asset:\n\n```dart\nalgorand.assetManager.createAsset(\n    account: account,\n    assetName: 'FlutterCoin',\n    unitName: 'Flutter',\n    totalAssets: 10000,\n    decimals: 2,\n);\n```\n\n## Features\n* Algod\n* Indexer\n* KMD\n* AVM 1.1 \u0026 TEAL v6 support\n* Transactions\n* Authorization\n* Atomic Transfers\n* Account management\n* Asset management\n* Smart Contracts\n* Flutter 3.0 support :heart:\n\n## Getting started\n\n### Installation\n\nYou can install the package via pub.dev:\n\n```bash\nalgorand_dart: ^latest-version\n```\n\n\u003e **Note**: Algorand-dart requires Dart \u003e=2.12.0 \u0026 null safety\n\u003e See the latest version on pub.dev\n\n## Usage\nCreate an ```AlgodClient```, ```IndexerClient``` and ```KmdClient``` and pass them to the ```Algorand``` constructor.\nWe added extra support for locally hosted nodes \u0026 third party services (like PureStake).\n\n```dart\nfinal algodClient = AlgodClient(\n    apiUrl: PureStake.TESTNET_ALGOD_API_URL,\n    apiKey: apiKey,\n    tokenKey: PureStake.API_TOKEN_HEADER,\n);\n\nfinal indexerClient = IndexerClient(\n    apiUrl: PureStake.TESTNET_INDEXER_API_URL,\n    apiKey: apiKey,\n    tokenKey: PureStake.API_TOKEN_HEADER,\n);\n\nfinal kmdClient = KmdClient(\n    apiUrl: '127.0.0.1',\n    apiKey: apiKey,\n);\n\nfinal algorand = Algorand(\n    algodClient: algodClient,\n    indexerClient: indexerClient,\n    kmdClient: kmdClient,\n);\n```\n\n## Ecosystem integrations\n\n* [AlgoSigner](https://pub.dev/packages/flutter_algosigner) - A Flutter web plugin to approve or deny Algorand transactions from within your browser using AlgoSigner.\n* [MyAlgo Connect](https://pub.dev/packages/flutter_myalgo_connect) - A Flutter web plugin to approve or deny Algorand transactions using MyAlgo Connect.\n* [WalletConnect](https://pub.dev/packages/walletconnect_dart) - Open protocol for connecting decentralised applications to mobile wallets with QR code scanning or deep linking.\n\n## Account Management\nAccounts are entities on the Algorand blockchain associated with specific onchain data, like a balance. An Algorand Address is the identifier for an Algorand account.\n\n### Creating a new account\n\nCreating a new account is as easy as calling:\n```dart\nfinal account = await algorand.createAccount();\n```\n\nOr you can always use the ```Account``` class.\n```dart\nfinal account = await Account.random();\n```\n\nWith the given account, you can easily extract the public Algorand address, signing keys and seedphrase/mnemonic.\n```dart\nfinal publicAddress = account.publicAddress;\nfinal words = await account.seedPhrase;\n```\n\n### Loading an existing account\n\nYou can load an existing account using your **generated secret key or binary seed**.\n\n```dart\nfinal account = await algorand.loadAccountFromSeed(seed);\n```\n\n### Restoring an account\n\nRecovering an account from your 25-word mnemonic/seedphrase can be done by passing an **array or space delimited string**\n\n```dart\nfinal restoredAccount = await algorand.restoreAccount([/* 25 words */]);\n```\n\n## Transactions\nThere are multiple ways to create a transaction. We've included helper functions to make our life easier.\n\n```dart\nalgorand.sendPayment(\n    account: account,\n    recipient: newAccount.address,\n    amount: Algo.toMicroAlgos(5),\n    note: 'Hi from Flutter!',\n);\n```\n\nThis will broadcast the transaction and immediately returns the transaction id, however you can also wait until the transaction is confirmed in a block using:\n\n```dart\nfinal transactionId = await algorand.sendPayment(\n    account: account,\n    recipient: newAccount.address,\n    amount: Algo.toMicroAlgos(5),\n    note: 'Hi from Flutter!',\n    waitForConfirmation: true,\n    timeout: 3,\n);\n```\n\nV2 of the Algorand Dart SDK includes some new helper functions to easily construct transactions:\n\n```dart\nfinal payTx = await algorand.createPaymentTransaction(\n    sender: account1.address,\n    receiver: fundAppAddress,\n    amount: 1e5.toInt(),\n);\n```\n\nOr you can use the ```TransactionBuilder``` to create more specific, raw transactions:\n\n```dart\n// Fetch the suggested transaction params\nfinal params = await algorand.getSuggestedTransactionParams();\n\n// Build the transaction\nfinal transaction = await (PaymentTransactionBuilder()\n    ..sender = account.address\n    ..note = 'Hi from Flutter'\n    ..amount = Algo.toMicroAlgos(5)\n    ..receiver = recipient\n    ..suggestedParams = params)\n  .build();\n\n// Sign the transaction\nfinal signedTx = await transaction.sign(account);\n\n// Send the transaction\nfinal txId = await algorand.sendTransaction(signedTx);\n```\n\n## Atomic Transfer\nAn Atomic Transfer means that transactions that are part of the transfer either all succeed or all fail.\nAtomic transfers allow complete strangers to trade assets without the need for a trusted intermediary,\nall while guaranteeing that each party will receive what they agreed to.\n\nAtomic transfers enable use cases such as:\n\n* **Circular trades** - Alice pays Bob if and only if Bob pays Claire if and only if Claire pays Alice.\n* **Group payments** - Everyone pays or no one pays.\n* **Decentralized exchanges** - Trade one asset for another without going through a centralized exchange.\n* **Distributed payments** - Payments to multiple recipients.\n\nAn atomic transfer can be created as following:\n\n```dart\n// Fetch the suggested transaction params\nfinal params = await algorand.getSuggestedTransactionParams();\n\n// Build the transaction\nfinal transactionA = await (PaymentTransactionBuilder()\n    ..sender = accountA.address\n    ..note = 'Atomic transfer from account A to account B'\n    ..amount = Algo.toMicroAlgos(1.2)\n    ..receiver = accountB.address\n    ..suggestedParams = params)\n  .build();\n\nfinal transactionB = await (PaymentTransactionBuilder()\n    ..sender = accountB.address\n    ..note = 'Atomic transfer from account B to account A'\n    ..amount = Algo.toMicroAlgos(2)\n    ..receiver = accountA.address\n    ..suggestedParams = params)\n  .build();\n\n// Combine the transactions and calculate the group id\nAtomicTransfer.group([transactionA, transactionB]);\n\n// Sign the transactions\nfinal signedTxA = await transactionA.sign(accountA);\nfinal signedTxB = await transactionB.sign(accountB);\n\n// Send the transactions\nfinal txId = await algorand.sendTransactions([signedTxA, signedTxB]);\n```\n\n## Asset Management\n\n**Create a new asset**\n\nCreating a new asset is as simple as using the ```AssetManager``` included in the Algorand SDK:\n\n```dart\nfinal transactionId = await algorand.assetManager.createAsset(\n    account: account,\n    assetName: 'FlutterCoin',\n    unitName: 'Flutter',\n    totalAssets: 10000,\n    decimals: 2,\n);\n```\n\nOr as usual, you can use the ```TransactionBuilder``` to create your asset:\n\n```dart\n// Fetch the suggested transaction params\nfinal params = await algorand.getSuggestedTransactionParams();\n\nfinal transaction = await (AssetConfigTransactionBuilder()\n      ..assetName = 'FlutterCoin'\n      ..unitName = 'Flutter'\n      ..totalAssetsToCreate = 10000\n      ..decimals = 2\n      ..defaultFrozen = false\n      ..managerAddress = account.address\n      ..reserveAddress = account.address\n      ..freezeAddress = account.address\n      ..clawbackAddress = account.address\n      ..sender = account.address\n      ..suggestedParams = params)\n    .build();\n\n// Sign the transactions\nfinal signedTransaction = await transaction.sign(account);\n\n// Send the transaction\nfinal txId = await algorand.sendTransaction(signedTransaction);\n```\n\n**Edit an asset**\n\nAfter an asset has been created only the manager, reserve, freeze and clawback accounts can be changed.\nAll other parameters are locked for the life of the asset.\n\nIf any of these addresses are set to \"\" that address will be cleared and can never be reset for the life of the asset.\nOnly the manager account can make configuration changes and must authorize the transaction.\n\n```dart\nalgorand.assetManager.editAsset(\n    assetId: 14618993,\n    account: account,\n    managerAddress: account.address,\n    reserveAddress: account.address,\n    freezeAddress: account.address,\n    clawbackAddress: account.address,\n);\n```\n\n**Destroy an asset**\n\n```dart\nalgorand.assetManager.destroyAsset(assetId: 14618993, account: account);\n```\n\n**Opt in to receive an asset**\n\nBefore being able to receive an asset, you should opt in\nAn opt-in transaction is simply an asset transfer with an amount of 0, both to and from the account opting in.\nAssets can be transferred between accounts that have opted-in to receiving the asset.\n\n```dart\nalgorand.assetManager.optIn(assetId: 14618993, account: account);\n```\n\n**Transfer an asset**\n\nTransfer an asset from the account to the receiver.\nAssets can be transferred between accounts that have opted-in to receiving the asset.\nThese are analogous to standard payment transactions but for Algorand Standard Assets.\n\n```dart\nalgorand.assetManager.transfer(assetId: 14618993, account: account, receiver: receiver, amount: 1000);\n```\n\n**Freeze an asset**\n\nFreezing or unfreezing an asset requires a transaction that is signed by the freeze account.\n\nUpon creation of an asset, you can specify a freeze address and a defaultfrozen state.\nIf the defaultfrozen state is set to true the corresponding freeze address must issue unfreeze transactions,\nto allow trading of the asset to and from that account.\nThis may be useful in situations that require holders of the asset to pass certain checks prior to ownership.\n\n```dart\nalgorand.assetManager.freeze(\n    assetId: 14618993,\n    account: account,\n    freezeTarget:\n    newAccount.address,\n    freeze: true,\n)\n```\n\n**Revoking an asset**\n\nRevoking an asset for an account removes a specific number of the asset from the revoke target account.\nRevoking an asset from an account requires specifying an asset sender (the revoke target account) and an\nasset receiver (the account to transfer the funds back to).\n\n```dart\nalgorand.assetManager.revoke(\n    assetId: 14618993,\n    account: account,\n    amount: 1000,\n    revokeAddress: account.address,\n  );\n```\n\n## Stateless Smart Contracts\n\nMost Algorand transactions are authorized by a signature from a single account or a multisignature account.\nAlgorand’s stateful smart contracts allow for a third type of signature using a\nTransaction Execution Approval Language (TEAL) program, called a logic signature (LogicSig).\nStateless smart contracts provide two modes for TEAL logic to operate as a LogicSig,\nto create a contract account that functions similar to an escrow or to delegate signature authority to another account.\n\n### Contract Account\n\nContract accounts are great for setting up escrow style accounts where you want to limit withdrawals or you want to do periodic payments, etc.\nTo spend from a contract account, create a transaction that will evaluate to True against the TEAL logic,\nthen add the compiled TEAL code as its logic signature.\nIt is worth noting that anyone can create and submit the transaction that spends from a contract account as long as they have the compiled TEAL contract to add as a logic signature.\n\nSample teal file\n```teal\n// samplearg.teal\n// This code is meant for learning purposes only\n// It should not be used in production\narg_0\nbtoi\nint 123\n==\n```\n\n```dart\nfinal arguments = \u003cUint8List\u003e[];\narguments.add(Uint8List.fromList([123]));\n\nfinal result =\n    await algorand.applicationManager.compileTEAL(sampleArgsTeal);\nfinal logicSig = LogicSignature.fromProgram(\n  program: result.program,\n  arguments: arguments,\n);\n\nfinal receiver =\n    'KTFZ5SQU3AQ6UFYI2QOWF5X5XJTAFRHACWHXAZV6CPLNKS2KSGQWPT4ACE';\nfinal params = await algorand.getSuggestedTransactionParams();\nfinal transaction = await (PaymentTransactionBuilder()\n      ..sender = logicSig.toAddress()\n      ..note = 'Logic Signature'\n      ..amount = 100000\n      ..receiver = Address.fromAlgorandAddress(receiver)\n      ..suggestedParams = params)\n    .build();\n\n// Sign the logic transaction\nfinal signedTx = await logicSig.signTransaction(transaction: transaction);\n\n// Send the transaction\nfinal txId = await algorand.sendTransaction(\n  signedTx,\n  waitForConfirmation: true,\n);\n```\n\n### Account Delegation\n\nStateless smart contracts can also be used to delegate signatures, which means that a private key can sign a TEAL program\nand the resulting output can be used as a signature in transactions on behalf of the account associated with the private key.\nThe owner of the delegated account can share this logic signature, allowing anyone to spend funds from his or her account according to the logic within the TEAL program.\n\n```dart\nfinal arguments = \u003cUint8List\u003e[];\narguments.add(Uint8List.fromList([123]));\n\nfinal result =\n    await algorand.applicationManager.compileTEAL(sampleArgsTeal);\nfinal logicSig = await LogicSignature.fromProgram(\n  program: result.program,\n  arguments: arguments,\n).sign(account: account);\n\nfinal receiver =\n    'KTFZ5SQU3AQ6UFYI2QOWF5X5XJTAFRHACWHXAZV6CPLNKS2KSGQWPT4ACE';\nfinal params = await algorand.getSuggestedTransactionParams();\nfinal transaction = await (PaymentTransactionBuilder()\n      ..sender = account.address\n      ..note = 'Account delegation'\n      ..amount = 100000\n      ..receiver = Address.fromAlgorandAddress(receiver)\n      ..suggestedParams = params)\n    .build();\n\n// Sign the logic transaction\nfinal signedTx = await logicSig.signTransaction(transaction: transaction);\n\n// Send the transaction\nfinal txId = await algorand.sendTransaction(\n  signedTx,\n  waitForConfirmation: true,\n);\n```\n\n## Stateful Smart Contracts\nStateful smart contracts are contracts that live on the chain and are used to keep track of some form of global and/or local state for the contract.\nStateful smart contracts form the backbone of applications that intend to run on the Algorand blockchain. Stateful smart contracts act similar to Algorand ASAs in that they have specific global values and per-user values.\n\n**Create a new application**\n\nBefore creating a stateful smart contract, the code for the ApprovalProgram and the ClearStateProgram program should be written.\nThe creator is the account that is creating the application and this transaction is signed by this account.\nThe approval program and the clear state program should also be provided.\nThe number of global and local byte slices (byte-array value) and integers also needs to be specified.\nThese represent the absolute on-chain amount of space that the smart contract will use.\nOnce set, these values can never be changed.\n\nWhen the smart contract is created the network will return a unique ApplicationID.\nThis ID can then be used to make ApplicationCall transactions to the smart contract.\n\n```dart\n// declare application state storage (immutable)\nfinal localInts = 1;\nfinal localBytes = 1;\nfinal globalInts = 1;\nfinal globalBytes = 0;\n\nfinal txId = await algorand.applicationManager.createApplicationFromSource(\n  account: account,\n  approvalProgramSource: approvalProgramSource,\n  clearProgramSource: clearProgramSource,\n  globalStateSchema: StateSchema(\n    numUint: globalInts,\n    numByteSlice: globalBytes,\n  ),\n  localStateSchema: StateSchema(\n    numUint: localInts,\n    numByteSlice: localBytes,\n  ),\n);\n```\n\nOr you can build the raw transaction using the ```ApplicationCreateTransactionBuilder```.\n\n```dart\n// declare application state storage (immutable)\nfinal localInts = 1;\nfinal localBytes = 1;\nfinal globalInts = 1;\nfinal globalBytes = 0;\n\nfinal approvalProgram =\n    await algorand.applicationManager.compileTEAL(approvalProgramSource);\n\nfinal clearProgram =\n    await algorand.applicationManager.compileTEAL(clearProgramSource);\n\nfinal params = await algorand.getSuggestedTransactionParams();\n\nfinal transaction = await (ApplicationCreateTransactionBuilder()\n      ..sender = account.address\n      ..approvalProgram = approvalProgram.program\n      ..clearStateProgram = clearProgram.program\n      ..globalStateSchema = StateSchema(\n        numUint: globalInts,\n        numByteSlice: globalBytes,\n      )\n      ..localStateSchema = StateSchema(\n        numUint: localInts,\n        numByteSlice: localBytes,\n      )\n      ..suggestedParams = params)\n    .build();\n\nfinal signedTx = await transaction.sign(account);\nfinal txId = await algorand.sendTransaction(\n  signedTx,\n  waitForConfirmation: true,\n);\n```\n\n**Opt into the Smart Contract**\n\nBefore any account, including the creator of the smart contract, can begin to make Application\nTransaction calls that use local state, it must first opt into the smart contract.\nThis prevents accounts from being spammed with smart contracts.\nTo opt in, an ApplicationCall transaction of type OptIn needs to be signed and submitted by the\naccount desiring to opt into the smart contract.\n\n```dart\nfinal txId = await algorand.applicationManager.optIn(\n  account: account,\n  applicationId: 19964146,\n);\n```\n\nOr you can build the raw transaction using the ```ApplicationOptInTransactionBuilder```.\n\n```\nfinal params = await algorand.getSuggestedTransactionParams();\n\nfinal transaction = await (ApplicationOptInTransactionBuilder()\n      ..sender = account.address\n      ..applicationId = 19964146\n      ..suggestedParams = params)\n    .build();\n\nfinal signedTx = await transaction.sign(account);\nfinal txId = await algorand.sendTransaction(\n  signedTx,\n  waitForConfirmation: true,\n);\n```\n\n**Calling a Stateful Smart Contract**\n\nOnce an account has opted into a stateful smart contract it can begin to make calls to the contract.\nDepending on the individual type of transaction as described in The Lifecycle of a Stateful Smart\nContract, either the ApprovalProgram or the ClearStateProgram will be called.\nGenerally, individual calls will supply application arguments.\nSee [Passing Arguments to a Smart Contract](https://developer.algorand.org/docs/features/asc1/stateful/#passing-arguments-to-stateful-smart-contracts) for details on passing arguments.\n\n```dart\nfinal txId = algorand.applicationManager.call(\n  account: account,\n  applicationId: 19964146,\n  arguments: arguments,\n);\n```\n\nOr you can build the raw transaction using the ```ApplicationCallTransactionBuilder```.\n\n```dart\nfinal arguments = 'str:arg1,int:12'.toApplicationArguments();\nfinal params = await algorand.getSuggestedTransactionParams();\n\nfinal transaction = await (ApplicationCallTransactionBuilder()\n      ..sender = account.address\n      ..applicationId = 19964146\n      ..arguments = arguments\n      ..suggestedParams = params)\n    .build();\n\nfinal signedTx = await transaction.sign(account);\nfinal txId = await algorand.sendTransaction(\n  signedTx,\n  waitForConfirmation: true,\n);\n```\n\n**Update a Stateful Smart Contract**\n\nA stateful smart contract’s programs can be updated at any time.\nThis is done by an ApplicationCall transaction type of UpdateApplication.\nThis operation requires passing the new programs and specifying the application ID.\nThe one caveat to this operation is that global or local state requirements for the smart contract can never be updated.\n\n```dart\nfinal approvalProgram =\n    await algorand.applicationManager.compileTEAL(approvalProgramSource);\n\nfinal clearProgram =\n    await algorand.applicationManager.compileTEAL(clearProgramSource);\n\nfinal txId = await algorand.applicationManager.update(\n  account: account,\n  applicationId: 19964146,\n  approvalProgram: approvalProgram.program,\n  clearProgram: clearProgram.program,\n);\n```\n\nOr you can build the raw transaction using the ```ApplicationUpdateTransactionBuilder```.\n\n```dart\nfinal approvalProgram =\n    await algorand.applicationManager.compileTEAL(approvalProgramSource);\n\nfinal clearProgram =\n    await algorand.applicationManager.compileTEAL(clearProgramSource);\n\nfinal params = await algorand.getSuggestedTransactionParams();\n\nfinal transaction = await (ApplicationUpdateTransactionBuilder()\n      ..sender = account.address\n      ..applicationId = 19964146\n      ..approvalProgram = approvalProgram.program\n      ..clearStateProgram = clearProgram.program\n      ..suggestedParams = params)\n    .build();\n\nfinal signedTx = await transaction.sign(account);\nfinal txId = await algorand.sendTransaction(\n  signedTx,\n  waitForConfirmation: true,\n);\n```\n\n**Delete a Stateful Smart Contract**\n\nTo delete a smart contract, an ApplicationCall transaction of type DeleteApplication must be submitted to the blockchain.\nThe ApprovalProgram handles this transaction type and if the call returns true the application will be deleted.\n\n```\nfinal txId = await algorand.applicationManager.delete(\n  account: account,\n  applicationId: 19964146,\n);\n```\n\n**Close out**\n\nThe user may discontinue use of the application by sending a close out transaction. This will remove the local state for this application from the user's account\n\n```dart\nfinal txId = await algorand.applicationManager.close(\n  account: account,\n  applicationId: 19964146,\n);\n```\n\n**Clear state**\n\nThe user may clear the local state for an application at any time, even if the application was deleted by the creator. This method uses the same 3 parameter.\n\n```dart\nfinal txId = await algorand.applicationManager.clearState(\n  account: account,\n  applicationId: 19964146,\n);\n```\n\n## Atomic Transaction Composer - ABI method calling\n\nWith the introduction of AVM 1.1, it is now possible to use the Atomic Transaction Composer (ATC).\nATC is a convenient way to build out an atomic group of transactions that handles encoding and decoding of ABI arguments and return values.\nThe example folder contains some examples from the Algorand DevRel team.\n\nTo use the Atomic Transaction Composer, first initialize the composer:\n\n```dart\nfinal atc = AtomicTransactionComposer();\n```\n\n**Add individual transactions**\n\nIndividual transactions being passed to the composer must be wrapped in a `TransactionWithSigner`.\n\nConstructing a Transaction with Signer and adding it to the transaction composer can be done as follows:\n\n```dart\nfinal payTx = await algorand.createPaymentTransaction(\n    sender: account.address,\n    receiver: appAddress,\n    amount: 1e5.toInt(),\n);\n\natc.addTransaction(TransactionWithSigner(transaction: payTx, signer: account));\n```\n\nThe call to add a transaction may be performed multiple times, each time adding a new transaction to the atomic group. Recall that a maximum of 16 transactions may be included in a single group.\n\n**Calling ABI methods**\n\nWhen calling an ABI compliant application, the Atomic Transaction Composer will handle encoding and decoding of the arguments passed and the return value. \nIt will also make sure that any reference types are packed into the transaction group appropriately. \nAdditionally, since it knows the method signature and types required, it will do some type checking to make sure the arguments passed are valid for the method call.\n\nIn order to call the methods, a Contract or Interface is constructed. Typically this will be done using a json file that describes the api for the application.\n\nOnce the Contract object is constructed, it can be used to look up and pass method objects into the Atomic Transaction Composers `addMethodCall`.\n\n```dart\nFuture\u003cAbiContract\u003e getContract() async {\n  // Read in the contract\n  final contractPath = join(dirname(Platform.script.path), 'contract.json');\n  return AbiContract.fromFile(contractPath);\n}\n\nawait atc.addMethodCall(MethodCallParams(\n    applicationId: appId,\n    sender: account.address,\n    method: findMethod(contract, 'acct_param'),\n    params: params,\n    signer: account,\n    methodArgs: [account1.address],\n));\n```\n\n**Execution**\nOnce all the transactions are added to the atomic group the Atomic Transaction Composer allows several ways to perform the transactions.\n\n- Build Group will construct the group of transactions and taking care of assigning the group id, returning an array of unsigned TransactionWithSigner objects.\n- Submit will call build group first, then gather the signatures associated to the transactions, then submit the group without blocking. It will return the full list of transaction ids that can be passed to a wait for confirmation function.\n- Execute will perform submit then wait for confirmation given a number of rounds. It will return the resulting confirmed round, list of transaction ids and any parsed ABI return values if relevant.\n\n```dart\n// Run the transaction and wait for the results\nfinal result = await atc.execute(algorand, waitRounds: 4);\n\n// Print out the results\nprint('Result of inner app call: ${result.methodResults[0]}');\n```\n\n## Multi Signatures\nMultisignature accounts are a logical representation of an ordered set of addresses with a threshold and version.\nMultisignature accounts can perform the same operations as other accounts, including sending transactions and participating in consensus.\nThe address for a multisignature account is essentially a hash of the ordered list of accounts, the threshold and version values.\nThe threshold determines how many signatures are required to process any transaction from this multisignature account.\n\n**Create a multisignature address**\n\n```dart\nfinal one = Address.fromAlgorandAddress(\n  address: 'XMHLMNAVJIMAW2RHJXLXKKK4G3J3U6VONNO3BTAQYVDC3MHTGDP3J5OCRU',\n);\nfinal two = Address.fromAlgorandAddress(\n  address: 'HTNOX33OCQI2JCOLZ2IRM3BC2WZ6JUILSLEORBPFI6W7GU5Q4ZW6LINHLA',\n);\n\nfinal three = Address.fromAlgorandAddress(\n  address: 'E6JSNTY4PVCY3IRZ6XEDHEO6VIHCQ5KGXCIQKFQCMB2N6HXRY4IB43VSHI',\n);\n\nfinal publicKeys = [one, two, three]\n    .map((address) =\u003e Ed25519PublicKey(bytes: address.publicKey))\n    .toList();\n\nfinal multiSigAddr =\n    MultiSigAddress(version: 1, threshold: 2, publicKeys: publicKeys);\n```\n\n**Sign a transaction with a multisignature account**\nThis section shows how to create, sign, and send a transaction from a multisig account.\n\n```dart\nfinal account1 = await Account.fromSeed(seed1);\nfinal account2 = await Account.fromSeed(seed2);\nfinal account3 = await Account.fromSeed(seed3);\n\nfinal publicKeys = [account1, account2, account3]\n    .map((account) =\u003e Ed25519PublicKey(bytes: account.address.publicKey))\n    .toList();\n\nfinal msa =\n    MultiSigAddress(version: 1, threshold: 2, publicKeys: publicKeys);\n\nfinal params = await algorand.getSuggestedTransactionParams();\nfinal transaction = await (PaymentTransactionBuilder()\n      ..sender = msa.toAddress()\n      ..note = 'MSA '\n      ..amount = 1000000\n      ..receiver = account3.address\n      ..suggestedParams = params)\n    .build();\n\n// Sign the transaction with the first account.\nfinal signedTx = await msa.sign(\n  account: account1,\n  transaction: transaction,\n);\n\nfinal completeTx = await msa.append(\n  account: account2,\n  transaction: signedTx,\n);\n\n// Send the transaction\nfinal txId = await algorand.sendTransaction(\n  completeTx,\n  waitForConfirmation: true,\n);\n```\n\n## Key Management Daemon\n\nThe Key Management Daemon (kmd) is a low level wallet and key management tool. It works in conjunction with algod and goal to keep secrets safe.\nkmd tries to ensure that secret keys never touch the disk unencrypted.\n\n* kmd has a data directory separate from algod's data directory. By default, however, the kmd data directory is in the kmd subdirectory of algod's data directory.\n* kmd starts an HTTP API server on localhost:7833 by default.\n* You talk to the HTTP API by sending json-serialized request structs from the kmdapi package.\n\nNote: If you are using a third-party API service, this process likely will not be available to you.\n\n```dart\nfinal request = (CreateWalletRequestBuilder()\n      ..walletName = 'wallet'\n      ..walletPassword = 'test'\n      ..walletDriverName = 'sqlite')\n    .build();\n\nfinal response = await algorand.kmd.createWallet(createWalletRequest: request);\n```\n\nCheck out the [Algorand Developer documentation ](https://developer.algorand.org/docs/features/accounts/create/#wallet-derived-kmd) to learn more about the Key Management Daemon.\n\n## Indexer\nAlgorand provides a standalone daemon algorand-indexer that reads committed blocks from the Algorand blockchain and\nmaintains a local database of transactions and accounts that are searchable and indexed.\n\nThe Dart SDK makes it really easy to search the ledger in a fluent api and enables application developers to perform rich and efficient queries on accounts,\ntransactions, assets, and so forth.\n\nAt the moment we support queries on transactions, assets and accounts.\n\n### Transactions\nAllow searching all transactions that have occurred on the blockchain.\n\n```dart\nfinal transactions = await algorand\n  .indexer()\n  .transactions()\n  .whereCurrencyIsLessThan(Algo.toMicroAlgos(1000))\n  .whereCurrencyIsGreaterThan(Algo.toMicroAlgos(500))\n  .whereAssetId(14618993)\n  .whereNotePrefix('Flutter')\n  .whereTransactionType(TransactionType.PAYMENT)\n  .search(limit: 5);\n```\n\n### Assets\nAllow searching all assets that are created on the blockchain.\n\n```dart\nfinal assets = await algorand\n  .indexer()\n  .assets()\n  .whereCurrencyIsLessThan(Algo.toMicroAlgos(1000))\n  .whereCurrencyIsGreaterThan(Algo.toMicroAlgos(500))\n  .whereAssetId(14618993)\n  .whereUnitName('Flutter')\n  .whereCreator(account.publicAddress)\n  .search(limit: 5);\n```\n### Accounts\nAllow searching all accounts that are created on the blockchain.\n\n```dart\nfinal accounts = await algorand\n      .indexer()\n      .accounts()\n      .whereCurrencyIsLessThan(Algo.toMicroAlgos(1000))\n      .whereCurrencyIsGreaterThan(Algo.toMicroAlgos(500))\n      .whereAssetId(14618993)\n      .whereAuthAddress(account.publicAddress)\n      .search(limit: 5);\n```\n\n### Applications\nAllow searching all applications on the blockchain.\n\n```dart\nfinal applications = await algorand\n    .indexer()\n    .applications()\n    .whereApplicationId(19964146)\n    .limit(5)\n    .search();\n```\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing \u0026 Pull Requests\nFeel free to send pull requests.\n\nPlease see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.\n\n## Credits\n\n- [Tomas Verhelst](https://github.com/rootsoft)\n- [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n\n\n\u003c!-- MARKDOWN LINKS \u0026 IMAGES --\u003e\n\u003c!-- https://www.markdownguide.org/basic-syntax/#reference-style-links --\u003e\n[pub-dev-shield]: https://img.shields.io/pub/v/algorand_dart?style=for-the-badge\n[pub-dev-url]: https://pub.dev/packages/algorand_dart\n[effective-dart-shield]: https://img.shields.io/badge/style-effective_dart-40c4ff.svg?style=for-the-badge\n[effective-dart-url]: https://github.com/tenhobi/effective_dart\n[stars-shield]: https://img.shields.io/github/stars/rootsoft/algorand-dart.svg?style=for-the-badge\u0026logo=github\u0026colorB=deeppink\u0026label=stars\n[stars-url]: https://packagist.org/packages/rootsoft/algorand-dart\n[issues-shield]: https://img.shields.io/github/issues/rootsoft/algorand-dart.svg?style=for-the-badge\n[issues-url]: https://github.com/rootsoft/algorand-dart/issues\n[license-shield]: https://img.shields.io/github/license/rootsoft/algorand-dart.svg?style=for-the-badge\n[license-url]: https://github.com/RootSoft/algorand-dart/blob/master/LICENSE","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frootsoft%2Falgorand-dart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frootsoft%2Falgorand-dart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frootsoft%2Falgorand-dart/lists"}