@algorandfoundation/algokit-utils 10.0.0-alpha.31 → 10.0.0-alpha.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. package/account-manager.d.ts +448 -0
  2. package/account-manager.js +623 -0
  3. package/account-manager.js.map +1 -0
  4. package/account-manager.mjs +620 -0
  5. package/account-manager.mjs.map +1 -0
  6. package/account.d.ts +156 -0
  7. package/account.js +10 -0
  8. package/account.js.map +1 -0
  9. package/account.mjs +9 -0
  10. package/account.mjs.map +1 -0
  11. package/algorand-client-transaction-creator.d.ts +1103 -0
  12. package/algorand-client-transaction-creator.js +735 -0
  13. package/algorand-client-transaction-creator.js.map +1 -0
  14. package/algorand-client-transaction-creator.mjs +734 -0
  15. package/algorand-client-transaction-creator.mjs.map +1 -0
  16. package/algorand-client-transaction-sender.d.ts +1317 -0
  17. package/algorand-client-transaction-sender.js +933 -0
  18. package/algorand-client-transaction-sender.js.map +1 -0
  19. package/algorand-client-transaction-sender.mjs +932 -0
  20. package/algorand-client-transaction-sender.mjs.map +1 -0
  21. package/algorand-client.d.ts +246 -0
  22. package/algorand-client.js +325 -0
  23. package/algorand-client.js.map +1 -0
  24. package/algorand-client.mjs +325 -0
  25. package/algorand-client.mjs.map +1 -0
  26. package/amount.d.ts +46 -3
  27. package/amount.js +92 -13
  28. package/amount.js.map +1 -1
  29. package/amount.mjs +80 -3
  30. package/amount.mjs.map +1 -1
  31. package/app-client.d.ts +2130 -0
  32. package/app-client.js +909 -0
  33. package/app-client.js.map +1 -0
  34. package/app-client.mjs +908 -0
  35. package/app-client.mjs.map +1 -0
  36. package/app-deployer.d.ts +166 -0
  37. package/app-deployer.js +353 -0
  38. package/app-deployer.js.map +1 -0
  39. package/app-deployer.mjs +353 -0
  40. package/app-deployer.mjs.map +1 -0
  41. package/app-factory.d.ts +965 -0
  42. package/app-factory.js +448 -0
  43. package/app-factory.js.map +1 -0
  44. package/app-factory.mjs +448 -0
  45. package/app-factory.mjs.map +1 -0
  46. package/app-manager.d.ts +323 -0
  47. package/app-manager.js +468 -0
  48. package/app-manager.js.map +1 -0
  49. package/app-manager.mjs +468 -0
  50. package/app-manager.mjs.map +1 -0
  51. package/app-spec.d.ts +203 -0
  52. package/app-spec.js +137 -0
  53. package/app-spec.js.map +1 -0
  54. package/app-spec.mjs +137 -0
  55. package/app-spec.mjs.map +1 -0
  56. package/app.d.ts +257 -0
  57. package/app.js +49 -0
  58. package/app.js.map +1 -0
  59. package/app.mjs +42 -0
  60. package/app.mjs.map +1 -0
  61. package/asset-manager.d.ts +212 -0
  62. package/asset-manager.js +166 -0
  63. package/asset-manager.js.map +1 -0
  64. package/asset-manager.mjs +166 -0
  65. package/asset-manager.mjs.map +1 -0
  66. package/async-event-emitter.d.ts +16 -0
  67. package/async-event-emitter.js +38 -0
  68. package/async-event-emitter.js.map +1 -0
  69. package/async-event-emitter.mjs +37 -0
  70. package/async-event-emitter.mjs.map +1 -0
  71. package/client-manager.d.ts +475 -0
  72. package/client-manager.js +616 -0
  73. package/client-manager.js.map +1 -0
  74. package/client-manager.mjs +616 -0
  75. package/client-manager.mjs.map +1 -0
  76. package/composer.d.ts +947 -0
  77. package/composer.js +1584 -0
  78. package/composer.js.map +1 -0
  79. package/composer.mjs +1583 -0
  80. package/composer.mjs.map +1 -0
  81. package/config.d.ts +1 -1
  82. package/config.js +2 -2
  83. package/config.js.map +1 -1
  84. package/config.mjs +1 -1
  85. package/config.mjs.map +1 -1
  86. package/debugging.d.ts +47 -0
  87. package/debugging.js +20 -0
  88. package/debugging.js.map +1 -0
  89. package/debugging.mjs +15 -0
  90. package/debugging.mjs.map +1 -0
  91. package/dispenser-client.d.ts +90 -0
  92. package/dispenser-client.js +127 -0
  93. package/dispenser-client.js.map +1 -0
  94. package/dispenser-client.mjs +127 -0
  95. package/dispenser-client.mjs.map +1 -0
  96. package/expand.d.ts +2 -0
  97. package/expand.js +0 -0
  98. package/expand.mjs +0 -0
  99. package/index.d.ts +6 -5
  100. package/index.js +4 -3
  101. package/index.mjs +5 -5
  102. package/indexer-client/indexer-lookup.d.ts +1 -1
  103. package/indexer-client/indexer-lookup.js.map +1 -1
  104. package/indexer-client/indexer-lookup.mjs.map +1 -1
  105. package/indexer.d.ts +40 -0
  106. package/indexer.js +38 -0
  107. package/indexer.js.map +1 -0
  108. package/indexer.mjs +35 -0
  109. package/indexer.mjs.map +1 -0
  110. package/instance-of.d.ts +8 -0
  111. package/kmd-account-manager.d.ts +74 -0
  112. package/kmd-account-manager.js +167 -0
  113. package/kmd-account-manager.js.map +1 -0
  114. package/kmd-account-manager.mjs +165 -0
  115. package/kmd-account-manager.mjs.map +1 -0
  116. package/lifecycle-events.d.ts +14 -0
  117. package/lifecycle-events.js +11 -0
  118. package/lifecycle-events.js.map +1 -0
  119. package/lifecycle-events.mjs +10 -0
  120. package/lifecycle-events.mjs.map +1 -0
  121. package/logging.d.ts +13 -0
  122. package/logging.js +47 -0
  123. package/logging.js.map +1 -0
  124. package/logging.mjs +42 -0
  125. package/logging.mjs.map +1 -0
  126. package/logic-error.d.ts +39 -0
  127. package/logic-error.js +54 -0
  128. package/logic-error.js.map +1 -0
  129. package/logic-error.mjs +53 -0
  130. package/logic-error.mjs.map +1 -0
  131. package/network-client.d.ts +43 -0
  132. package/network-client.js +14 -0
  133. package/network-client.js.map +1 -0
  134. package/network-client.mjs +13 -0
  135. package/network-client.mjs.map +1 -0
  136. package/package.json +11 -1
  137. package/testing/account.d.ts +2 -2
  138. package/testing/account.js +1 -1
  139. package/testing/account.js.map +1 -1
  140. package/testing/account.mjs +1 -1
  141. package/testing/account.mjs.map +1 -1
  142. package/testing/fixtures/algokit-log-capture-fixture.d.ts +1 -1
  143. package/testing/fixtures/algokit-log-capture-fixture.js.map +1 -1
  144. package/testing/fixtures/algokit-log-capture-fixture.mjs.map +1 -1
  145. package/testing/fixtures/algorand-fixture.d.ts +2 -2
  146. package/testing/fixtures/algorand-fixture.js +2 -2
  147. package/testing/fixtures/algorand-fixture.js.map +1 -1
  148. package/testing/fixtures/algorand-fixture.mjs +2 -2
  149. package/testing/fixtures/algorand-fixture.mjs.map +1 -1
  150. package/testing/index.d.ts +2 -1
  151. package/testing/test-logger.d.ts +1 -1
  152. package/testing/test-logger.js.map +1 -1
  153. package/testing/test-logger.mjs.map +1 -1
  154. package/testing/types.d.ts +156 -0
  155. package/transaction/index.d.ts +4 -0
  156. package/transaction/index.js +9 -0
  157. package/transaction/index.mjs +4 -0
  158. package/transaction/perform-transaction-composer-simulate.d.ts +1 -1
  159. package/transaction/perform-transaction-composer-simulate.js.map +1 -1
  160. package/transaction/perform-transaction-composer-simulate.mjs.map +1 -1
  161. package/transaction/transaction.d.ts +2 -2
  162. package/transaction/transaction.js.map +1 -1
  163. package/transaction/transaction.mjs.map +1 -1
  164. package/transaction/types.d.ts +133 -0
  165. package/transactions/app-call.d.ts +1 -1
  166. package/transactions/app-call.js +1 -1
  167. package/transactions/app-call.js.map +1 -1
  168. package/transactions/app-call.mjs +1 -1
  169. package/transactions/app-call.mjs.map +1 -1
  170. package/transactions/common.d.ts +1 -1
  171. package/transactions/common.js.map +1 -1
  172. package/transactions/common.mjs.map +1 -1
  173. package/transactions/method-call.d.ts +1 -1
  174. package/transactions/method-call.js +1 -1
  175. package/transactions/method-call.js.map +1 -1
  176. package/transactions/method-call.mjs +1 -1
  177. package/transactions/method-call.mjs.map +1 -1
  178. package/transactions/payment.d.ts +1 -1
  179. package/transactions/payment.js.map +1 -1
  180. package/transactions/payment.mjs.map +1 -1
  181. package/types/account-manager.d.ts +11 -442
  182. package/types/account-manager.js +5 -616
  183. package/types/account-manager.js.map +1 -1
  184. package/types/account-manager.mjs +5 -614
  185. package/types/account-manager.mjs.map +1 -1
  186. package/types/account.d.ts +8 -150
  187. package/types/account.js +3 -4
  188. package/types/account.js.map +1 -1
  189. package/types/account.mjs +4 -4
  190. package/types/account.mjs.map +1 -1
  191. package/types/algorand-client-transaction-creator.d.ts +5 -1098
  192. package/types/algorand-client-transaction-creator.js +3 -729
  193. package/types/algorand-client-transaction-creator.js.map +1 -1
  194. package/types/algorand-client-transaction-creator.mjs +4 -729
  195. package/types/algorand-client-transaction-creator.mjs.map +1 -1
  196. package/types/algorand-client-transaction-sender.d.ts +5 -1312
  197. package/types/algorand-client-transaction-sender.js +3 -927
  198. package/types/algorand-client-transaction-sender.js.map +1 -1
  199. package/types/algorand-client-transaction-sender.mjs +3 -926
  200. package/types/algorand-client-transaction-sender.mjs.map +1 -1
  201. package/types/algorand-client.d.ts +5 -241
  202. package/types/algorand-client.js +3 -319
  203. package/types/algorand-client.js.map +1 -1
  204. package/types/algorand-client.mjs +3 -319
  205. package/types/algorand-client.mjs.map +1 -1
  206. package/types/amount.d.ts +6 -45
  207. package/types/amount.js +3 -79
  208. package/types/amount.js.map +1 -1
  209. package/types/amount.mjs +4 -79
  210. package/types/amount.mjs.map +1 -1
  211. package/types/app-client.d.ts +75 -2125
  212. package/types/app-client.js +3 -903
  213. package/types/app-client.js.map +1 -1
  214. package/types/app-client.mjs +3 -902
  215. package/types/app-client.mjs.map +1 -1
  216. package/types/app-deployer.d.ts +21 -161
  217. package/types/app-deployer.js +3 -347
  218. package/types/app-deployer.js.map +1 -1
  219. package/types/app-deployer.mjs +3 -347
  220. package/types/app-deployer.mjs.map +1 -1
  221. package/types/app-factory.d.ts +21 -960
  222. package/types/app-factory.js +3 -442
  223. package/types/app-factory.js.map +1 -1
  224. package/types/app-factory.mjs +3 -442
  225. package/types/app-factory.mjs.map +1 -1
  226. package/types/app-manager.d.ts +15 -318
  227. package/types/app-manager.js +3 -462
  228. package/types/app-manager.js.map +1 -1
  229. package/types/app-manager.mjs +3 -462
  230. package/types/app-manager.mjs.map +1 -1
  231. package/types/app-spec.d.ts +39 -198
  232. package/types/app-spec.js +3 -131
  233. package/types/app-spec.js.map +1 -1
  234. package/types/app-spec.mjs +3 -131
  235. package/types/app-spec.mjs.map +1 -1
  236. package/types/app.d.ts +62 -247
  237. package/types/app.js +15 -37
  238. package/types/app.js.map +1 -1
  239. package/types/app.mjs +16 -37
  240. package/types/app.mjs.map +1 -1
  241. package/types/asset-manager.d.ts +9 -207
  242. package/types/asset-manager.js +3 -160
  243. package/types/asset-manager.js.map +1 -1
  244. package/types/asset-manager.mjs +3 -160
  245. package/types/asset-manager.mjs.map +1 -1
  246. package/types/async-event-emitter.d.ts +7 -11
  247. package/types/async-event-emitter.js +3 -32
  248. package/types/async-event-emitter.js.map +1 -1
  249. package/types/async-event-emitter.mjs +4 -32
  250. package/types/async-event-emitter.mjs.map +1 -1
  251. package/types/client-manager.d.ts +27 -470
  252. package/types/client-manager.js +3 -610
  253. package/types/client-manager.js.map +1 -1
  254. package/types/client-manager.mjs +3 -610
  255. package/types/client-manager.mjs.map +1 -1
  256. package/types/composer.d.ts +79 -943
  257. package/types/composer.js +3 -1578
  258. package/types/composer.js.map +1 -1
  259. package/types/composer.mjs +3 -1577
  260. package/types/composer.mjs.map +1 -1
  261. package/types/config.d.ts +7 -52
  262. package/types/config.js +3 -74
  263. package/types/config.js.map +1 -1
  264. package/types/config.mjs +3 -74
  265. package/types/config.mjs.map +1 -1
  266. package/types/debugging.d.ts +12 -37
  267. package/types/debugging.js +11 -10
  268. package/types/debugging.js.map +1 -1
  269. package/types/debugging.mjs +12 -10
  270. package/types/debugging.mjs.map +1 -1
  271. package/types/dispenser-client.d.ts +11 -85
  272. package/types/dispenser-client.js +3 -121
  273. package/types/dispenser-client.js.map +1 -1
  274. package/types/dispenser-client.mjs +3 -121
  275. package/types/dispenser-client.mjs.map +1 -1
  276. package/types/expand.d.ts +8 -2
  277. package/types/indexer.d.ts +16 -36
  278. package/types/indexer.js +7 -30
  279. package/types/indexer.js.map +1 -1
  280. package/types/indexer.mjs +8 -30
  281. package/types/indexer.mjs.map +1 -1
  282. package/types/instance-of.d.ts +4 -4
  283. package/types/kmd-account-manager.d.ts +5 -69
  284. package/types/kmd-account-manager.js +3 -161
  285. package/types/kmd-account-manager.js.map +1 -1
  286. package/types/kmd-account-manager.mjs +3 -159
  287. package/types/kmd-account-manager.mjs.map +1 -1
  288. package/types/lifecycle-events.d.ts +7 -9
  289. package/types/lifecycle-events.js +3 -5
  290. package/types/lifecycle-events.js.map +1 -1
  291. package/types/lifecycle-events.mjs +4 -5
  292. package/types/lifecycle-events.mjs.map +1 -1
  293. package/types/logging.d.ts +14 -9
  294. package/types/logging.js +11 -37
  295. package/types/logging.js.map +1 -1
  296. package/types/logging.mjs +12 -37
  297. package/types/logging.mjs.map +1 -1
  298. package/types/logic-error.d.ts +8 -35
  299. package/types/logic-error.js +3 -48
  300. package/types/logic-error.js.map +1 -1
  301. package/types/logic-error.mjs +4 -48
  302. package/types/logic-error.mjs.map +1 -1
  303. package/types/network-client.d.ts +10 -39
  304. package/types/network-client.js +3 -8
  305. package/types/network-client.js.map +1 -1
  306. package/types/network-client.mjs +4 -8
  307. package/types/network-client.mjs.map +1 -1
  308. package/types/testing.d.ts +13 -151
  309. package/types/transaction.d.ts +33 -128
  310. package/updatable-config.d.ts +57 -0
  311. package/updatable-config.js +80 -0
  312. package/updatable-config.js.map +1 -0
  313. package/updatable-config.mjs +80 -0
  314. package/updatable-config.mjs.map +1 -0
  315. package/util.js +1 -1
  316. package/util.js.map +1 -1
  317. package/util.mjs +1 -1
  318. package/util.mjs.map +1 -1
@@ -0,0 +1,167 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.js');
2
+ const require_address = require('./packages/common/src/address.js');
3
+ const require_amount = require('./amount.js');
4
+ const require_config = require('./config.js');
5
+ const require_signer = require('./packages/transact/src/signer.js');
6
+ const require_composer = require('./composer.js');
7
+ const require_client_manager = require('./client-manager.js');
8
+ let tweetnacl = require("tweetnacl");
9
+ tweetnacl = require_rolldown_runtime.__toESM(tweetnacl);
10
+
11
+ //#region src/kmd-account-manager.ts
12
+ /** Provides abstractions over a [KMD](https://github.com/algorand/go-algorand/blob/master/daemon/kmd/README.md) instance
13
+ * that makes it easier to get and manage accounts using KMD. */
14
+ var KmdAccountManager = class {
15
+ _clientManager;
16
+ _kmd;
17
+ /**
18
+ * Create a new KMD manager.
19
+ * @param clientManager A ClientManager client to use for algod and kmd clients
20
+ */
21
+ constructor(clientManager) {
22
+ this._clientManager = clientManager;
23
+ try {
24
+ this._kmd = clientManager.kmd;
25
+ } catch {
26
+ this._kmd = void 0;
27
+ }
28
+ }
29
+ async kmd() {
30
+ if (this._kmd === void 0) {
31
+ if (await this._clientManager.isLocalNet()) {
32
+ const { kmdConfig } = require_client_manager.ClientManager.getConfigFromEnvironmentOrLocalNet();
33
+ if (kmdConfig) {
34
+ this._kmd = require_client_manager.ClientManager.getKmdClient(kmdConfig);
35
+ return this._kmd;
36
+ }
37
+ }
38
+ this._kmd = null;
39
+ }
40
+ if (!this._kmd) throw new Error("Attempt to use Kmd client in AlgoKit instance with no Kmd configured");
41
+ return this._kmd;
42
+ }
43
+ /**
44
+ * Returns an Algorand signing account with private key loaded from the given KMD wallet (identified by name).
45
+ *
46
+ * @param walletName The name of the wallet to retrieve an account from
47
+ * @param predicate An optional filter to use to find the account (otherwise it will return a random account from the wallet)
48
+ * @param sender The optional sender address to use this signer for (aka a rekeyed account)
49
+ * @example Get default funded account in a LocalNet
50
+ *
51
+ * ```typescript
52
+ * const defaultDispenserAccount = await kmdAccountManager.getWalletAccount(
53
+ * 'unencrypted-default-wallet',
54
+ * a => a.status !== 'Offline' && a.amount > 1_000_000_000
55
+ * )
56
+ * ```
57
+ * @returns The signing account (with private key loaded) or undefined if no matching wallet or account was found
58
+ */
59
+ async getWalletAccount(walletName, predicate, sender) {
60
+ return this.findWalletAccount(walletName, predicate, sender);
61
+ }
62
+ async findWalletAccount(walletName, predicateOrAddress, sender) {
63
+ const kmd = await this.kmd();
64
+ const wallet = (await kmd.listWallets()).wallets.filter((w) => w.name === walletName);
65
+ if (wallet.length === 0) return;
66
+ const walletHandle = (await kmd.initWalletHandle({
67
+ walletId: wallet[0].id,
68
+ walletPassword: ""
69
+ })).walletHandleToken;
70
+ let matchedAddress = void 0;
71
+ if (predicateOrAddress && typeof predicateOrAddress === "string") matchedAddress = require_address.Address.fromString(predicateOrAddress);
72
+ else {
73
+ const addresses = (await kmd.listKeysInWallet({ walletHandleToken: walletHandle })).addresses;
74
+ if (addresses.length > 0) if (predicateOrAddress && typeof predicateOrAddress === "function") {
75
+ for (let i = 0; i < addresses.length; i++) if (predicateOrAddress(await this._clientManager.algod.accountInformation(addresses[i]))) {
76
+ matchedAddress = addresses[i];
77
+ break;
78
+ }
79
+ } else matchedAddress = addresses[0];
80
+ }
81
+ if (!matchedAddress) return;
82
+ const accountKey = (await kmd.exportKey({
83
+ walletHandleToken: walletHandle,
84
+ address: matchedAddress
85
+ })).privateKey;
86
+ const keys = tweetnacl.default.sign.keyPair.fromSecretKey(accountKey);
87
+ const rawSigner = async (bytesToSign) => {
88
+ return tweetnacl.default.sign.detached(bytesToSign, keys.secretKey);
89
+ };
90
+ return require_signer.generateAddressWithSigners({
91
+ ed25519Pubkey: keys.publicKey,
92
+ sendingAddress: require_address.getOptionalAddress(sender),
93
+ rawEd25519Signer: rawSigner
94
+ });
95
+ }
96
+ /**
97
+ * Gets an account with private key loaded from a KMD wallet of the given name, or alternatively creates one with funds in it via a KMD wallet of the given name.
98
+ *
99
+ * This is useful to get idempotent accounts from LocalNet without having to specify the private key (which will change when resetting the LocalNet).
100
+ *
101
+ * This significantly speeds up local dev time and improves experience since you can write code that *just works* first go without manual config in a fresh LocalNet.
102
+ *
103
+ * If this is used via `mnemonicAccountFromEnvironment`, then you can even use the same code that runs on production without changes for local development!
104
+ *
105
+ * @param name The name of the wallet to retrieve / create
106
+ * @param fundWith The number of Algo to fund the account with when it gets created, if not specified then 1000 ALGO will be funded from the dispenser account
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * // Idempotently get (if exists) or create (if it doesn't exist yet) an account by name using KMD
111
+ * // if creating it then fund it with 2 ALGO from the default dispenser account
112
+ * const newAccount = await kmdAccountManager.getOrCreateWalletAccount('account1', (2).algo())
113
+ * // This will return the same account as above since the name matches
114
+ * const existingAccount = await kmdAccountManager.getOrCreateWalletAccount('account1')
115
+ * ```
116
+ *
117
+ * @returns An Algorand account with private key loaded - either one that already existed in the given KMD wallet, or a new one that is funded for you
118
+ */
119
+ async getOrCreateWalletAccount(name, fundWith) {
120
+ const existing = await this.getWalletAccount(name);
121
+ if (existing) return existing;
122
+ const kmd = await this.kmd();
123
+ const walletId = (await kmd.createWallet({
124
+ walletName: name,
125
+ walletPassword: ""
126
+ })).wallet.id;
127
+ const walletHandle = (await kmd.initWalletHandle({
128
+ walletId,
129
+ walletPassword: ""
130
+ })).walletHandleToken;
131
+ await kmd.generateKey({ walletHandleToken: walletHandle });
132
+ const account = await this.getWalletAccount(name);
133
+ require_config.Config.logger.info(`LocalNet account '${name}' doesn't yet exist; created account ${account.addr} with keys stored in KMD and funding with ${fundWith?.algo ?? 1e3} ALGO`);
134
+ const dispenser = await this.getLocalNetDispenserAccount();
135
+ await new require_composer.TransactionComposer({
136
+ algod: this._clientManager.algod,
137
+ getSigner: () => dispenser.signer,
138
+ getSuggestedParams: () => this._clientManager.algod.suggestedParams()
139
+ }).addPayment({
140
+ amount: fundWith ?? require_amount.AlgoAmount.Algo(1e3),
141
+ receiver: account.addr,
142
+ sender: dispenser.addr
143
+ }).send();
144
+ return account;
145
+ }
146
+ /**
147
+ * Returns an Algorand account with private key loaded for the default LocalNet dispenser account (that can be used to fund other accounts).
148
+ * @example
149
+ * ```typescript
150
+ * const dispenser = await kmdAccountManager.getLocalNetDispenserAccount()
151
+ * ```
152
+ * @returns The default LocalNet dispenser account
153
+ */
154
+ async getLocalNetDispenserAccount() {
155
+ if (!await this._clientManager.isLocalNet()) throw new Error("Can't get LocalNet dispenser account from non LocalNet network");
156
+ const dispenserAddresses = (await this._clientManager.algod.genesis()).alloc.filter((a) => a.comment === "Wallet1").map((a) => a.addr);
157
+ if (dispenserAddresses.length > 0) {
158
+ const dispenser = await this.findWalletAccount("unencrypted-default-wallet", dispenserAddresses[0]);
159
+ if (dispenser) return dispenser;
160
+ }
161
+ throw new Error("Error retrieving LocalNet dispenser account; couldn't find the default account in KMD");
162
+ }
163
+ };
164
+
165
+ //#endregion
166
+ exports.KmdAccountManager = KmdAccountManager;
167
+ //# sourceMappingURL=kmd-account-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kmd-account-manager.js","names":["ClientManager","matchedAddress: Address | undefined","Address","nacl","generateAddressWithSigners","getOptionalAddress","TransactionComposer","AlgoAmount"],"sources":["../src/kmd-account-manager.ts"],"sourcesContent":["import { Account } from '@algorandfoundation/algokit-algod-client'\nimport { Address, getOptionalAddress } from '@algorandfoundation/algokit-common'\nimport { KmdClient } from '@algorandfoundation/algokit-kmd-client'\nimport { AddressWithTransactionSigner, generateAddressWithSigners } from '@algorandfoundation/algokit-transact'\nimport nacl from 'tweetnacl'\nimport { AlgoAmount } from './amount'\nimport { ClientManager } from './client-manager'\nimport { TransactionComposer } from './composer'\nimport { Config } from './config'\n\n/** Provides abstractions over a [KMD](https://github.com/algorand/go-algorand/blob/master/daemon/kmd/README.md) instance\n * that makes it easier to get and manage accounts using KMD. */\nexport class KmdAccountManager {\n private _clientManager: Omit<ClientManager, 'kmd'>\n private _kmd?: KmdClient | null\n\n /**\n * Create a new KMD manager.\n * @param clientManager A ClientManager client to use for algod and kmd clients\n */\n constructor(clientManager: ClientManager) {\n this._clientManager = clientManager\n try {\n this._kmd = clientManager.kmd\n } catch {\n this._kmd = undefined\n }\n }\n\n async kmd(): Promise<KmdClient> {\n if (this._kmd === undefined) {\n if (await this._clientManager.isLocalNet()) {\n const { kmdConfig } = ClientManager.getConfigFromEnvironmentOrLocalNet()\n if (kmdConfig) {\n this._kmd = ClientManager.getKmdClient(kmdConfig)\n return this._kmd\n }\n }\n this._kmd = null\n }\n\n if (!this._kmd) {\n throw new Error('Attempt to use Kmd client in AlgoKit instance with no Kmd configured')\n }\n\n return this._kmd\n }\n\n /**\n * Returns an Algorand signing account with private key loaded from the given KMD wallet (identified by name).\n *\n * @param walletName The name of the wallet to retrieve an account from\n * @param predicate An optional filter to use to find the account (otherwise it will return a random account from the wallet)\n * @param sender The optional sender address to use this signer for (aka a rekeyed account)\n * @example Get default funded account in a LocalNet\n *\n * ```typescript\n * const defaultDispenserAccount = await kmdAccountManager.getWalletAccount(\n * 'unencrypted-default-wallet',\n * a => a.status !== 'Offline' && a.amount > 1_000_000_000\n * )\n * ```\n * @returns The signing account (with private key loaded) or undefined if no matching wallet or account was found\n */\n public async getWalletAccount(\n walletName: string,\n predicate?: (account: Account) => boolean,\n sender?: string | Address,\n ): Promise<AddressWithTransactionSigner | undefined> {\n return this.findWalletAccount(walletName, predicate, sender)\n }\n\n private async findWalletAccount(\n walletName: string,\n predicateOrAddress?: ((account: Account) => boolean) | string,\n sender?: string | Address,\n ): Promise<AddressWithTransactionSigner | undefined> {\n const kmd = await this.kmd()\n const walletsResponse = await kmd.listWallets()\n const wallet = walletsResponse.wallets.filter((w) => w.name === walletName)\n if (wallet.length === 0) {\n return undefined\n }\n const walletId = wallet[0].id\n const walletHandle = (await kmd.initWalletHandle({ walletId, walletPassword: '' })).walletHandleToken\n\n let matchedAddress: Address | undefined = undefined\n if (predicateOrAddress && typeof predicateOrAddress === 'string') {\n matchedAddress = Address.fromString(predicateOrAddress)\n } else {\n const addresses = (await kmd.listKeysInWallet({ walletHandleToken: walletHandle })).addresses\n if (addresses.length > 0) {\n if (predicateOrAddress && typeof predicateOrAddress === 'function') {\n for (let i = 0; i < addresses.length; i++) {\n const account = await this._clientManager.algod.accountInformation(addresses[i])\n if (predicateOrAddress(account)) {\n matchedAddress = addresses[i]\n break\n }\n }\n } else {\n matchedAddress = addresses[0]\n }\n }\n }\n\n if (!matchedAddress) {\n return undefined\n }\n\n const accountKey = (await kmd.exportKey({ walletHandleToken: walletHandle, address: matchedAddress })).privateKey\n const keys = nacl.sign.keyPair.fromSecretKey(accountKey)\n const rawSigner = async (bytesToSign: Uint8Array): Promise<Uint8Array> => {\n return nacl.sign.detached(bytesToSign, keys.secretKey)\n }\n\n return generateAddressWithSigners({\n ed25519Pubkey: keys.publicKey,\n sendingAddress: getOptionalAddress(sender),\n rawEd25519Signer: rawSigner,\n })\n }\n\n /**\n * Gets an account with private key loaded from a KMD wallet of the given name, or alternatively creates one with funds in it via a KMD wallet of the given name.\n *\n * This is useful to get idempotent accounts from LocalNet without having to specify the private key (which will change when resetting the LocalNet).\n *\n * This significantly speeds up local dev time and improves experience since you can write code that *just works* first go without manual config in a fresh LocalNet.\n *\n * If this is used via `mnemonicAccountFromEnvironment`, then you can even use the same code that runs on production without changes for local development!\n *\n * @param name The name of the wallet to retrieve / create\n * @param fundWith The number of Algo to fund the account with when it gets created, if not specified then 1000 ALGO will be funded from the dispenser account\n *\n * @example\n * ```typescript\n * // Idempotently get (if exists) or create (if it doesn't exist yet) an account by name using KMD\n * // if creating it then fund it with 2 ALGO from the default dispenser account\n * const newAccount = await kmdAccountManager.getOrCreateWalletAccount('account1', (2).algo())\n * // This will return the same account as above since the name matches\n * const existingAccount = await kmdAccountManager.getOrCreateWalletAccount('account1')\n * ```\n *\n * @returns An Algorand account with private key loaded - either one that already existed in the given KMD wallet, or a new one that is funded for you\n */\n public async getOrCreateWalletAccount(name: string, fundWith?: AlgoAmount): Promise<AddressWithTransactionSigner> {\n // Get an existing account from the KMD wallet\n const existing = await this.getWalletAccount(name)\n if (existing) {\n return existing\n }\n\n const kmd = await this.kmd()\n\n // None existed: create the KMD wallet instead\n const walletId = (await kmd.createWallet({ walletName: name, walletPassword: '' })).wallet.id\n const walletHandle = (await kmd.initWalletHandle({ walletId, walletPassword: '' })).walletHandleToken\n await kmd.generateKey({ walletHandleToken: walletHandle })\n\n // Get the account from the new KMD wallet\n const account = (await this.getWalletAccount(name))!\n\n Config.logger.info(\n `LocalNet account '${name}' doesn't yet exist; created account ${account.addr} with keys stored in KMD and funding with ${\n fundWith?.algo ?? 1000\n } ALGO`,\n )\n\n // Fund the account from the dispenser\n const dispenser = await this.getLocalNetDispenserAccount()\n await new TransactionComposer({\n algod: this._clientManager.algod,\n getSigner: () => dispenser.signer,\n getSuggestedParams: () => this._clientManager.algod.suggestedParams(),\n })\n .addPayment({ amount: fundWith ?? AlgoAmount.Algo(1000), receiver: account.addr, sender: dispenser.addr })\n .send()\n\n return account\n }\n\n /**\n * Returns an Algorand account with private key loaded for the default LocalNet dispenser account (that can be used to fund other accounts).\n * @example\n * ```typescript\n * const dispenser = await kmdAccountManager.getLocalNetDispenserAccount()\n * ```\n * @returns The default LocalNet dispenser account\n */\n public async getLocalNetDispenserAccount() {\n if (!(await this._clientManager.isLocalNet())) {\n throw new Error(\"Can't get LocalNet dispenser account from non LocalNet network\")\n }\n const genesisResponse = await this._clientManager.algod.genesis()\n const dispenserAddresses = genesisResponse.alloc.filter((a) => a.comment === 'Wallet1').map((a) => a.addr)\n if (dispenserAddresses.length > 0) {\n const dispenser = await this.findWalletAccount('unencrypted-default-wallet', dispenserAddresses[0])\n if (dispenser) {\n return dispenser\n }\n }\n\n throw new Error(\"Error retrieving LocalNet dispenser account; couldn't find the default account in KMD\")\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,165 @@
1
+ import { Address, getOptionalAddress } from "./packages/common/src/address.mjs";
2
+ import { AlgoAmount } from "./amount.mjs";
3
+ import { Config } from "./config.mjs";
4
+ import { generateAddressWithSigners } from "./packages/transact/src/signer.mjs";
5
+ import { TransactionComposer } from "./composer.mjs";
6
+ import { ClientManager } from "./client-manager.mjs";
7
+ import nacl from "tweetnacl";
8
+
9
+ //#region src/kmd-account-manager.ts
10
+ /** Provides abstractions over a [KMD](https://github.com/algorand/go-algorand/blob/master/daemon/kmd/README.md) instance
11
+ * that makes it easier to get and manage accounts using KMD. */
12
+ var KmdAccountManager = class {
13
+ _clientManager;
14
+ _kmd;
15
+ /**
16
+ * Create a new KMD manager.
17
+ * @param clientManager A ClientManager client to use for algod and kmd clients
18
+ */
19
+ constructor(clientManager) {
20
+ this._clientManager = clientManager;
21
+ try {
22
+ this._kmd = clientManager.kmd;
23
+ } catch {
24
+ this._kmd = void 0;
25
+ }
26
+ }
27
+ async kmd() {
28
+ if (this._kmd === void 0) {
29
+ if (await this._clientManager.isLocalNet()) {
30
+ const { kmdConfig } = ClientManager.getConfigFromEnvironmentOrLocalNet();
31
+ if (kmdConfig) {
32
+ this._kmd = ClientManager.getKmdClient(kmdConfig);
33
+ return this._kmd;
34
+ }
35
+ }
36
+ this._kmd = null;
37
+ }
38
+ if (!this._kmd) throw new Error("Attempt to use Kmd client in AlgoKit instance with no Kmd configured");
39
+ return this._kmd;
40
+ }
41
+ /**
42
+ * Returns an Algorand signing account with private key loaded from the given KMD wallet (identified by name).
43
+ *
44
+ * @param walletName The name of the wallet to retrieve an account from
45
+ * @param predicate An optional filter to use to find the account (otherwise it will return a random account from the wallet)
46
+ * @param sender The optional sender address to use this signer for (aka a rekeyed account)
47
+ * @example Get default funded account in a LocalNet
48
+ *
49
+ * ```typescript
50
+ * const defaultDispenserAccount = await kmdAccountManager.getWalletAccount(
51
+ * 'unencrypted-default-wallet',
52
+ * a => a.status !== 'Offline' && a.amount > 1_000_000_000
53
+ * )
54
+ * ```
55
+ * @returns The signing account (with private key loaded) or undefined if no matching wallet or account was found
56
+ */
57
+ async getWalletAccount(walletName, predicate, sender) {
58
+ return this.findWalletAccount(walletName, predicate, sender);
59
+ }
60
+ async findWalletAccount(walletName, predicateOrAddress, sender) {
61
+ const kmd = await this.kmd();
62
+ const wallet = (await kmd.listWallets()).wallets.filter((w) => w.name === walletName);
63
+ if (wallet.length === 0) return;
64
+ const walletHandle = (await kmd.initWalletHandle({
65
+ walletId: wallet[0].id,
66
+ walletPassword: ""
67
+ })).walletHandleToken;
68
+ let matchedAddress = void 0;
69
+ if (predicateOrAddress && typeof predicateOrAddress === "string") matchedAddress = Address.fromString(predicateOrAddress);
70
+ else {
71
+ const addresses = (await kmd.listKeysInWallet({ walletHandleToken: walletHandle })).addresses;
72
+ if (addresses.length > 0) if (predicateOrAddress && typeof predicateOrAddress === "function") {
73
+ for (let i = 0; i < addresses.length; i++) if (predicateOrAddress(await this._clientManager.algod.accountInformation(addresses[i]))) {
74
+ matchedAddress = addresses[i];
75
+ break;
76
+ }
77
+ } else matchedAddress = addresses[0];
78
+ }
79
+ if (!matchedAddress) return;
80
+ const accountKey = (await kmd.exportKey({
81
+ walletHandleToken: walletHandle,
82
+ address: matchedAddress
83
+ })).privateKey;
84
+ const keys = nacl.sign.keyPair.fromSecretKey(accountKey);
85
+ const rawSigner = async (bytesToSign) => {
86
+ return nacl.sign.detached(bytesToSign, keys.secretKey);
87
+ };
88
+ return generateAddressWithSigners({
89
+ ed25519Pubkey: keys.publicKey,
90
+ sendingAddress: getOptionalAddress(sender),
91
+ rawEd25519Signer: rawSigner
92
+ });
93
+ }
94
+ /**
95
+ * Gets an account with private key loaded from a KMD wallet of the given name, or alternatively creates one with funds in it via a KMD wallet of the given name.
96
+ *
97
+ * This is useful to get idempotent accounts from LocalNet without having to specify the private key (which will change when resetting the LocalNet).
98
+ *
99
+ * This significantly speeds up local dev time and improves experience since you can write code that *just works* first go without manual config in a fresh LocalNet.
100
+ *
101
+ * If this is used via `mnemonicAccountFromEnvironment`, then you can even use the same code that runs on production without changes for local development!
102
+ *
103
+ * @param name The name of the wallet to retrieve / create
104
+ * @param fundWith The number of Algo to fund the account with when it gets created, if not specified then 1000 ALGO will be funded from the dispenser account
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * // Idempotently get (if exists) or create (if it doesn't exist yet) an account by name using KMD
109
+ * // if creating it then fund it with 2 ALGO from the default dispenser account
110
+ * const newAccount = await kmdAccountManager.getOrCreateWalletAccount('account1', (2).algo())
111
+ * // This will return the same account as above since the name matches
112
+ * const existingAccount = await kmdAccountManager.getOrCreateWalletAccount('account1')
113
+ * ```
114
+ *
115
+ * @returns An Algorand account with private key loaded - either one that already existed in the given KMD wallet, or a new one that is funded for you
116
+ */
117
+ async getOrCreateWalletAccount(name, fundWith) {
118
+ const existing = await this.getWalletAccount(name);
119
+ if (existing) return existing;
120
+ const kmd = await this.kmd();
121
+ const walletId = (await kmd.createWallet({
122
+ walletName: name,
123
+ walletPassword: ""
124
+ })).wallet.id;
125
+ const walletHandle = (await kmd.initWalletHandle({
126
+ walletId,
127
+ walletPassword: ""
128
+ })).walletHandleToken;
129
+ await kmd.generateKey({ walletHandleToken: walletHandle });
130
+ const account = await this.getWalletAccount(name);
131
+ Config.logger.info(`LocalNet account '${name}' doesn't yet exist; created account ${account.addr} with keys stored in KMD and funding with ${fundWith?.algo ?? 1e3} ALGO`);
132
+ const dispenser = await this.getLocalNetDispenserAccount();
133
+ await new TransactionComposer({
134
+ algod: this._clientManager.algod,
135
+ getSigner: () => dispenser.signer,
136
+ getSuggestedParams: () => this._clientManager.algod.suggestedParams()
137
+ }).addPayment({
138
+ amount: fundWith ?? AlgoAmount.Algo(1e3),
139
+ receiver: account.addr,
140
+ sender: dispenser.addr
141
+ }).send();
142
+ return account;
143
+ }
144
+ /**
145
+ * Returns an Algorand account with private key loaded for the default LocalNet dispenser account (that can be used to fund other accounts).
146
+ * @example
147
+ * ```typescript
148
+ * const dispenser = await kmdAccountManager.getLocalNetDispenserAccount()
149
+ * ```
150
+ * @returns The default LocalNet dispenser account
151
+ */
152
+ async getLocalNetDispenserAccount() {
153
+ if (!await this._clientManager.isLocalNet()) throw new Error("Can't get LocalNet dispenser account from non LocalNet network");
154
+ const dispenserAddresses = (await this._clientManager.algod.genesis()).alloc.filter((a) => a.comment === "Wallet1").map((a) => a.addr);
155
+ if (dispenserAddresses.length > 0) {
156
+ const dispenser = await this.findWalletAccount("unencrypted-default-wallet", dispenserAddresses[0]);
157
+ if (dispenser) return dispenser;
158
+ }
159
+ throw new Error("Error retrieving LocalNet dispenser account; couldn't find the default account in KMD");
160
+ }
161
+ };
162
+
163
+ //#endregion
164
+ export { KmdAccountManager };
165
+ //# sourceMappingURL=kmd-account-manager.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kmd-account-manager.mjs","names":["matchedAddress: Address | undefined"],"sources":["../src/kmd-account-manager.ts"],"sourcesContent":["import { Account } from '@algorandfoundation/algokit-algod-client'\nimport { Address, getOptionalAddress } from '@algorandfoundation/algokit-common'\nimport { KmdClient } from '@algorandfoundation/algokit-kmd-client'\nimport { AddressWithTransactionSigner, generateAddressWithSigners } from '@algorandfoundation/algokit-transact'\nimport nacl from 'tweetnacl'\nimport { AlgoAmount } from './amount'\nimport { ClientManager } from './client-manager'\nimport { TransactionComposer } from './composer'\nimport { Config } from './config'\n\n/** Provides abstractions over a [KMD](https://github.com/algorand/go-algorand/blob/master/daemon/kmd/README.md) instance\n * that makes it easier to get and manage accounts using KMD. */\nexport class KmdAccountManager {\n private _clientManager: Omit<ClientManager, 'kmd'>\n private _kmd?: KmdClient | null\n\n /**\n * Create a new KMD manager.\n * @param clientManager A ClientManager client to use for algod and kmd clients\n */\n constructor(clientManager: ClientManager) {\n this._clientManager = clientManager\n try {\n this._kmd = clientManager.kmd\n } catch {\n this._kmd = undefined\n }\n }\n\n async kmd(): Promise<KmdClient> {\n if (this._kmd === undefined) {\n if (await this._clientManager.isLocalNet()) {\n const { kmdConfig } = ClientManager.getConfigFromEnvironmentOrLocalNet()\n if (kmdConfig) {\n this._kmd = ClientManager.getKmdClient(kmdConfig)\n return this._kmd\n }\n }\n this._kmd = null\n }\n\n if (!this._kmd) {\n throw new Error('Attempt to use Kmd client in AlgoKit instance with no Kmd configured')\n }\n\n return this._kmd\n }\n\n /**\n * Returns an Algorand signing account with private key loaded from the given KMD wallet (identified by name).\n *\n * @param walletName The name of the wallet to retrieve an account from\n * @param predicate An optional filter to use to find the account (otherwise it will return a random account from the wallet)\n * @param sender The optional sender address to use this signer for (aka a rekeyed account)\n * @example Get default funded account in a LocalNet\n *\n * ```typescript\n * const defaultDispenserAccount = await kmdAccountManager.getWalletAccount(\n * 'unencrypted-default-wallet',\n * a => a.status !== 'Offline' && a.amount > 1_000_000_000\n * )\n * ```\n * @returns The signing account (with private key loaded) or undefined if no matching wallet or account was found\n */\n public async getWalletAccount(\n walletName: string,\n predicate?: (account: Account) => boolean,\n sender?: string | Address,\n ): Promise<AddressWithTransactionSigner | undefined> {\n return this.findWalletAccount(walletName, predicate, sender)\n }\n\n private async findWalletAccount(\n walletName: string,\n predicateOrAddress?: ((account: Account) => boolean) | string,\n sender?: string | Address,\n ): Promise<AddressWithTransactionSigner | undefined> {\n const kmd = await this.kmd()\n const walletsResponse = await kmd.listWallets()\n const wallet = walletsResponse.wallets.filter((w) => w.name === walletName)\n if (wallet.length === 0) {\n return undefined\n }\n const walletId = wallet[0].id\n const walletHandle = (await kmd.initWalletHandle({ walletId, walletPassword: '' })).walletHandleToken\n\n let matchedAddress: Address | undefined = undefined\n if (predicateOrAddress && typeof predicateOrAddress === 'string') {\n matchedAddress = Address.fromString(predicateOrAddress)\n } else {\n const addresses = (await kmd.listKeysInWallet({ walletHandleToken: walletHandle })).addresses\n if (addresses.length > 0) {\n if (predicateOrAddress && typeof predicateOrAddress === 'function') {\n for (let i = 0; i < addresses.length; i++) {\n const account = await this._clientManager.algod.accountInformation(addresses[i])\n if (predicateOrAddress(account)) {\n matchedAddress = addresses[i]\n break\n }\n }\n } else {\n matchedAddress = addresses[0]\n }\n }\n }\n\n if (!matchedAddress) {\n return undefined\n }\n\n const accountKey = (await kmd.exportKey({ walletHandleToken: walletHandle, address: matchedAddress })).privateKey\n const keys = nacl.sign.keyPair.fromSecretKey(accountKey)\n const rawSigner = async (bytesToSign: Uint8Array): Promise<Uint8Array> => {\n return nacl.sign.detached(bytesToSign, keys.secretKey)\n }\n\n return generateAddressWithSigners({\n ed25519Pubkey: keys.publicKey,\n sendingAddress: getOptionalAddress(sender),\n rawEd25519Signer: rawSigner,\n })\n }\n\n /**\n * Gets an account with private key loaded from a KMD wallet of the given name, or alternatively creates one with funds in it via a KMD wallet of the given name.\n *\n * This is useful to get idempotent accounts from LocalNet without having to specify the private key (which will change when resetting the LocalNet).\n *\n * This significantly speeds up local dev time and improves experience since you can write code that *just works* first go without manual config in a fresh LocalNet.\n *\n * If this is used via `mnemonicAccountFromEnvironment`, then you can even use the same code that runs on production without changes for local development!\n *\n * @param name The name of the wallet to retrieve / create\n * @param fundWith The number of Algo to fund the account with when it gets created, if not specified then 1000 ALGO will be funded from the dispenser account\n *\n * @example\n * ```typescript\n * // Idempotently get (if exists) or create (if it doesn't exist yet) an account by name using KMD\n * // if creating it then fund it with 2 ALGO from the default dispenser account\n * const newAccount = await kmdAccountManager.getOrCreateWalletAccount('account1', (2).algo())\n * // This will return the same account as above since the name matches\n * const existingAccount = await kmdAccountManager.getOrCreateWalletAccount('account1')\n * ```\n *\n * @returns An Algorand account with private key loaded - either one that already existed in the given KMD wallet, or a new one that is funded for you\n */\n public async getOrCreateWalletAccount(name: string, fundWith?: AlgoAmount): Promise<AddressWithTransactionSigner> {\n // Get an existing account from the KMD wallet\n const existing = await this.getWalletAccount(name)\n if (existing) {\n return existing\n }\n\n const kmd = await this.kmd()\n\n // None existed: create the KMD wallet instead\n const walletId = (await kmd.createWallet({ walletName: name, walletPassword: '' })).wallet.id\n const walletHandle = (await kmd.initWalletHandle({ walletId, walletPassword: '' })).walletHandleToken\n await kmd.generateKey({ walletHandleToken: walletHandle })\n\n // Get the account from the new KMD wallet\n const account = (await this.getWalletAccount(name))!\n\n Config.logger.info(\n `LocalNet account '${name}' doesn't yet exist; created account ${account.addr} with keys stored in KMD and funding with ${\n fundWith?.algo ?? 1000\n } ALGO`,\n )\n\n // Fund the account from the dispenser\n const dispenser = await this.getLocalNetDispenserAccount()\n await new TransactionComposer({\n algod: this._clientManager.algod,\n getSigner: () => dispenser.signer,\n getSuggestedParams: () => this._clientManager.algod.suggestedParams(),\n })\n .addPayment({ amount: fundWith ?? AlgoAmount.Algo(1000), receiver: account.addr, sender: dispenser.addr })\n .send()\n\n return account\n }\n\n /**\n * Returns an Algorand account with private key loaded for the default LocalNet dispenser account (that can be used to fund other accounts).\n * @example\n * ```typescript\n * const dispenser = await kmdAccountManager.getLocalNetDispenserAccount()\n * ```\n * @returns The default LocalNet dispenser account\n */\n public async getLocalNetDispenserAccount() {\n if (!(await this._clientManager.isLocalNet())) {\n throw new Error(\"Can't get LocalNet dispenser account from non LocalNet network\")\n }\n const genesisResponse = await this._clientManager.algod.genesis()\n const dispenserAddresses = genesisResponse.alloc.filter((a) => a.comment === 'Wallet1').map((a) => a.addr)\n if (dispenserAddresses.length > 0) {\n const dispenser = await this.findWalletAccount('unencrypted-default-wallet', dispenserAddresses[0])\n if (dispenser) {\n return dispenser\n }\n }\n\n throw new Error(\"Error retrieving LocalNet dispenser account; couldn't find the default account in KMD\")\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { AVMTracesEventData, TealSourcesDebugEventData } from "./debugging.js";
2
+
3
+ //#region src/lifecycle-events.d.ts
4
+ declare enum EventType {
5
+ TxnGroupSimulated = "TxnGroupSimulated",
6
+ AppCompiled = "AppCompiled",
7
+ }
8
+ type EventDataMap = {
9
+ [EventType.TxnGroupSimulated]: AVMTracesEventData;
10
+ [EventType.AppCompiled]: TealSourcesDebugEventData;
11
+ };
12
+ //#endregion
13
+ export { EventDataMap, EventType };
14
+ //# sourceMappingURL=lifecycle-events.d.ts.map
@@ -0,0 +1,11 @@
1
+
2
+ //#region src/lifecycle-events.ts
3
+ let EventType = /* @__PURE__ */ function(EventType$1) {
4
+ EventType$1["TxnGroupSimulated"] = "TxnGroupSimulated";
5
+ EventType$1["AppCompiled"] = "AppCompiled";
6
+ return EventType$1;
7
+ }({});
8
+
9
+ //#endregion
10
+ exports.EventType = EventType;
11
+ //# sourceMappingURL=lifecycle-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-events.js","names":[],"sources":["../src/lifecycle-events.ts"],"sourcesContent":["import { AVMTracesEventData, TealSourcesDebugEventData } from './debugging'\n\nexport enum EventType {\n TxnGroupSimulated = 'TxnGroupSimulated',\n AppCompiled = 'AppCompiled',\n}\n\nexport type EventDataMap = {\n [EventType.TxnGroupSimulated]: AVMTracesEventData\n [EventType.AppCompiled]: TealSourcesDebugEventData\n}\n"],"mappings":";;AAEA,IAAY,kDAAL;AACL;AACA"}
@@ -0,0 +1,10 @@
1
+ //#region src/lifecycle-events.ts
2
+ let EventType = /* @__PURE__ */ function(EventType$1) {
3
+ EventType$1["TxnGroupSimulated"] = "TxnGroupSimulated";
4
+ EventType$1["AppCompiled"] = "AppCompiled";
5
+ return EventType$1;
6
+ }({});
7
+
8
+ //#endregion
9
+ export { EventType };
10
+ //# sourceMappingURL=lifecycle-events.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-events.mjs","names":[],"sources":["../src/lifecycle-events.ts"],"sourcesContent":["import { AVMTracesEventData, TealSourcesDebugEventData } from './debugging'\n\nexport enum EventType {\n TxnGroupSimulated = 'TxnGroupSimulated',\n AppCompiled = 'AppCompiled',\n}\n\nexport type EventDataMap = {\n [EventType.TxnGroupSimulated]: AVMTracesEventData\n [EventType.AppCompiled]: TealSourcesDebugEventData\n}\n"],"mappings":";AAEA,IAAY,kDAAL;AACL;AACA"}
package/logging.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { Logger } from "./packages/common/src/logger.js";
2
+
3
+ //#region src/logging.d.ts
4
+ /** A logger implementation that writes to console */
5
+ declare const consoleLogger: Logger;
6
+ declare const infoConsoleLogger: Logger;
7
+ declare const verboseConsoleLogger: Logger;
8
+ declare const warningConsoleLogger: Logger;
9
+ /** A logger implementation that does nothing */
10
+ declare const nullLogger: Logger;
11
+ //#endregion
12
+ export { type Logger, consoleLogger, infoConsoleLogger, nullLogger, verboseConsoleLogger, warningConsoleLogger };
13
+ //# sourceMappingURL=logging.d.ts.map
package/logging.js ADDED
@@ -0,0 +1,47 @@
1
+
2
+ //#region src/logging.ts
3
+ /** A logger implementation that writes to console */
4
+ const consoleLogger = {
5
+ error: console.error,
6
+ warn: console.warn,
7
+ info: console.info,
8
+ verbose: () => {},
9
+ debug: console.debug
10
+ };
11
+ const infoConsoleLogger = {
12
+ error: console.error,
13
+ warn: console.warn,
14
+ info: console.info,
15
+ verbose: () => {},
16
+ debug: () => {}
17
+ };
18
+ const verboseConsoleLogger = {
19
+ error: console.error,
20
+ warn: console.warn,
21
+ info: console.info,
22
+ verbose: console.trace,
23
+ debug: console.debug
24
+ };
25
+ const warningConsoleLogger = {
26
+ error: console.error,
27
+ warn: console.warn,
28
+ info: () => {},
29
+ verbose: () => {},
30
+ debug: () => {}
31
+ };
32
+ /** A logger implementation that does nothing */
33
+ const nullLogger = {
34
+ error: function(message, ...optionalParams) {},
35
+ warn: function(message, ...optionalParams) {},
36
+ info: function(message, ...optionalParams) {},
37
+ verbose: function(message, ...optionalParams) {},
38
+ debug: function(message, ...optionalParams) {}
39
+ };
40
+
41
+ //#endregion
42
+ exports.consoleLogger = consoleLogger;
43
+ exports.infoConsoleLogger = infoConsoleLogger;
44
+ exports.nullLogger = nullLogger;
45
+ exports.verboseConsoleLogger = verboseConsoleLogger;
46
+ exports.warningConsoleLogger = warningConsoleLogger;
47
+ //# sourceMappingURL=logging.js.map
package/logging.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.js","names":["consoleLogger: Logger","infoConsoleLogger: Logger","verboseConsoleLogger: Logger","warningConsoleLogger: Logger","nullLogger: Logger"],"sources":["../src/logging.ts"],"sourcesContent":["/* eslint-disable unused-imports/no-unused-vars */\n/* eslint-disable no-console */\n\nimport type { Logger } from '@algorandfoundation/algokit-common'\nexport type { Logger } from '@algorandfoundation/algokit-common'\n\n/** A logger implementation that writes to console */\nexport const consoleLogger: Logger = {\n error: console.error,\n warn: console.warn,\n info: console.info,\n verbose: () => {},\n debug: console.debug,\n}\n\nexport const infoConsoleLogger: Logger = {\n error: console.error,\n warn: console.warn,\n info: console.info,\n verbose: () => {},\n debug: () => {},\n}\n\nexport const verboseConsoleLogger: Logger = {\n error: console.error,\n warn: console.warn,\n info: console.info,\n verbose: console.trace,\n debug: console.debug,\n}\n\nexport const warningConsoleLogger: Logger = {\n error: console.error,\n warn: console.warn,\n info: () => {},\n verbose: () => {},\n debug: () => {},\n}\n\n/** A logger implementation that does nothing */\nexport const nullLogger: Logger = {\n error: function (message: string, ...optionalParams: unknown[]): void {},\n warn: function (message: string, ...optionalParams: unknown[]): void {},\n info: function (message: string, ...optionalParams: unknown[]): void {},\n verbose: function (message: string, ...optionalParams: unknown[]): void {},\n debug: function (message: string, ...optionalParams: unknown[]): void {},\n}\n"],"mappings":";;;AAOA,MAAaA,gBAAwB;CACnC,OAAO,QAAQ;CACf,MAAM,QAAQ;CACd,MAAM,QAAQ;CACd,eAAe;CACf,OAAO,QAAQ;CAChB;AAED,MAAaC,oBAA4B;CACvC,OAAO,QAAQ;CACf,MAAM,QAAQ;CACd,MAAM,QAAQ;CACd,eAAe;CACf,aAAa;CACd;AAED,MAAaC,uBAA+B;CAC1C,OAAO,QAAQ;CACf,MAAM,QAAQ;CACd,MAAM,QAAQ;CACd,SAAS,QAAQ;CACjB,OAAO,QAAQ;CAChB;AAED,MAAaC,uBAA+B;CAC1C,OAAO,QAAQ;CACf,MAAM,QAAQ;CACd,YAAY;CACZ,eAAe;CACf,aAAa;CACd;;AAGD,MAAaC,aAAqB;CAChC,OAAO,SAAU,SAAiB,GAAG,gBAAiC;CACtE,MAAM,SAAU,SAAiB,GAAG,gBAAiC;CACrE,MAAM,SAAU,SAAiB,GAAG,gBAAiC;CACrE,SAAS,SAAU,SAAiB,GAAG,gBAAiC;CACxE,OAAO,SAAU,SAAiB,GAAG,gBAAiC;CACvE"}
package/logging.mjs ADDED
@@ -0,0 +1,42 @@
1
+ //#region src/logging.ts
2
+ /** A logger implementation that writes to console */
3
+ const consoleLogger = {
4
+ error: console.error,
5
+ warn: console.warn,
6
+ info: console.info,
7
+ verbose: () => {},
8
+ debug: console.debug
9
+ };
10
+ const infoConsoleLogger = {
11
+ error: console.error,
12
+ warn: console.warn,
13
+ info: console.info,
14
+ verbose: () => {},
15
+ debug: () => {}
16
+ };
17
+ const verboseConsoleLogger = {
18
+ error: console.error,
19
+ warn: console.warn,
20
+ info: console.info,
21
+ verbose: console.trace,
22
+ debug: console.debug
23
+ };
24
+ const warningConsoleLogger = {
25
+ error: console.error,
26
+ warn: console.warn,
27
+ info: () => {},
28
+ verbose: () => {},
29
+ debug: () => {}
30
+ };
31
+ /** A logger implementation that does nothing */
32
+ const nullLogger = {
33
+ error: function(message, ...optionalParams) {},
34
+ warn: function(message, ...optionalParams) {},
35
+ info: function(message, ...optionalParams) {},
36
+ verbose: function(message, ...optionalParams) {},
37
+ debug: function(message, ...optionalParams) {}
38
+ };
39
+
40
+ //#endregion
41
+ export { consoleLogger, infoConsoleLogger, nullLogger, verboseConsoleLogger, warningConsoleLogger };
42
+ //# sourceMappingURL=logging.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.mjs","names":["consoleLogger: Logger","infoConsoleLogger: Logger","verboseConsoleLogger: Logger","warningConsoleLogger: Logger","nullLogger: Logger"],"sources":["../src/logging.ts"],"sourcesContent":["/* eslint-disable unused-imports/no-unused-vars */\n/* eslint-disable no-console */\n\nimport type { Logger } from '@algorandfoundation/algokit-common'\nexport type { Logger } from '@algorandfoundation/algokit-common'\n\n/** A logger implementation that writes to console */\nexport const consoleLogger: Logger = {\n error: console.error,\n warn: console.warn,\n info: console.info,\n verbose: () => {},\n debug: console.debug,\n}\n\nexport const infoConsoleLogger: Logger = {\n error: console.error,\n warn: console.warn,\n info: console.info,\n verbose: () => {},\n debug: () => {},\n}\n\nexport const verboseConsoleLogger: Logger = {\n error: console.error,\n warn: console.warn,\n info: console.info,\n verbose: console.trace,\n debug: console.debug,\n}\n\nexport const warningConsoleLogger: Logger = {\n error: console.error,\n warn: console.warn,\n info: () => {},\n verbose: () => {},\n debug: () => {},\n}\n\n/** A logger implementation that does nothing */\nexport const nullLogger: Logger = {\n error: function (message: string, ...optionalParams: unknown[]): void {},\n warn: function (message: string, ...optionalParams: unknown[]): void {},\n info: function (message: string, ...optionalParams: unknown[]): void {},\n verbose: function (message: string, ...optionalParams: unknown[]): void {},\n debug: function (message: string, ...optionalParams: unknown[]): void {},\n}\n"],"mappings":";;AAOA,MAAaA,gBAAwB;CACnC,OAAO,QAAQ;CACf,MAAM,QAAQ;CACd,MAAM,QAAQ;CACd,eAAe;CACf,OAAO,QAAQ;CAChB;AAED,MAAaC,oBAA4B;CACvC,OAAO,QAAQ;CACf,MAAM,QAAQ;CACd,MAAM,QAAQ;CACd,eAAe;CACf,aAAa;CACd;AAED,MAAaC,uBAA+B;CAC1C,OAAO,QAAQ;CACf,MAAM,QAAQ;CACd,MAAM,QAAQ;CACd,SAAS,QAAQ;CACjB,OAAO,QAAQ;CAChB;AAED,MAAaC,uBAA+B;CAC1C,OAAO,QAAQ;CACf,MAAM,QAAQ;CACd,YAAY;CACZ,eAAe;CACf,aAAa;CACd;;AAGD,MAAaC,aAAqB;CAChC,OAAO,SAAU,SAAiB,GAAG,gBAAiC;CACtE,MAAM,SAAU,SAAiB,GAAG,gBAAiC;CACrE,MAAM,SAAU,SAAiB,GAAG,gBAAiC;CACrE,SAAS,SAAU,SAAiB,GAAG,gBAAiC;CACxE,OAAO,SAAU,SAAiB,GAAG,gBAAiC;CACvE"}
@@ -0,0 +1,39 @@
1
+ //#region src/logic-error.d.ts
2
+ /**
3
+ * Details about a smart contract logic error
4
+ */
5
+ interface LogicErrorDetails {
6
+ /** The ID of the transaction with the logic error */
7
+ txId: string;
8
+ /** The program counter where the error was */
9
+ pc: number;
10
+ /** The error message */
11
+ msg: string;
12
+ /** The full error description */
13
+ desc: string;
14
+ /** Any trace information included in the error */
15
+ traces: Record<string, unknown>[];
16
+ }
17
+ /** Wraps key functionality around processing logic errors */
18
+ declare class LogicError extends Error {
19
+ /** Takes an error message and parses out the details of any logic errors in there.
20
+ * @param error The error message to parse
21
+ * @returns The logic error details if any, or undefined
22
+ */
23
+ static parseLogicError(error: any): LogicErrorDetails | undefined;
24
+ led: LogicErrorDetails;
25
+ program: string[];
26
+ lines: number;
27
+ teal_line: number;
28
+ stack?: string;
29
+ /**
30
+ * Create a new logic error object.
31
+ * @param errorDetails The details of the logic error
32
+ * @param program The TEAL source code, split by line
33
+ * @param getLineForPc The source map of the TEAL source code
34
+ */
35
+ constructor(errorDetails: LogicErrorDetails, program: string[], getLineForPc: (pc: number) => number | undefined);
36
+ }
37
+ //#endregion
38
+ export { LogicError, LogicErrorDetails };
39
+ //# sourceMappingURL=logic-error.d.ts.map
package/logic-error.js ADDED
@@ -0,0 +1,54 @@
1
+
2
+ //#region src/logic-error.ts
3
+ const LOGIC_ERROR = /transaction ([A-Z0-9]+): logic eval error: (.*). Details: .*pc=([0-9]+).*/;
4
+ const INNER_LOGIC_ERROR = /inner tx (\d+) failed:.*?pc=([0-9]+)/;
5
+ /** Wraps key functionality around processing logic errors */
6
+ var LogicError = class extends Error {
7
+ /** Takes an error message and parses out the details of any logic errors in there.
8
+ * @param error The error message to parse
9
+ * @returns The logic error details if any, or undefined
10
+ */
11
+ static parseLogicError(error) {
12
+ const errorMessage = error.message;
13
+ const res = LOGIC_ERROR.exec(errorMessage);
14
+ const innerRes = INNER_LOGIC_ERROR.exec(errorMessage);
15
+ if (res === null || res.length <= 3) return void 0;
16
+ return {
17
+ txId: res[1],
18
+ msg: res[2],
19
+ desc: errorMessage,
20
+ pc: parseInt(innerRes?.[2] ?? res[3] ?? "0"),
21
+ traces: error.traces
22
+ };
23
+ }
24
+ led;
25
+ program;
26
+ lines = 5;
27
+ teal_line = 0;
28
+ stack;
29
+ /**
30
+ * Create a new logic error object.
31
+ * @param errorDetails The details of the logic error
32
+ * @param program The TEAL source code, split by line
33
+ * @param getLineForPc The source map of the TEAL source code
34
+ */
35
+ constructor(errorDetails, program, getLineForPc) {
36
+ super();
37
+ this.led = errorDetails;
38
+ this.program = program;
39
+ const line = getLineForPc(errorDetails.pc);
40
+ this.teal_line = line === void 0 ? 0 : line;
41
+ this.message = `${this.led.msg}. at:${line}. ${this.led.desc}`;
42
+ if (this.teal_line > 0) {
43
+ const start = this.teal_line > this.lines ? this.teal_line - this.lines : 0;
44
+ const stop = program.length > this.teal_line + this.lines ? this.teal_line + this.lines : program.length;
45
+ const stack_lines = program.slice(start, stop);
46
+ stack_lines[stack_lines.length / 2] += " <--- Error";
47
+ this.stack = stack_lines.join("\n");
48
+ }
49
+ }
50
+ };
51
+
52
+ //#endregion
53
+ exports.LogicError = LogicError;
54
+ //# sourceMappingURL=logic-error.js.map