@algorandfoundation/algokit-utils 1.0.0-beta.9 → 1.1.0

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 (158) hide show
  1. package/README.md +38 -0
  2. package/account.d.ts +41 -36
  3. package/account.d.ts.map +1 -1
  4. package/account.js +59 -44
  5. package/account.js.map +1 -1
  6. package/amount.d.ts +20 -0
  7. package/amount.d.ts.map +1 -0
  8. package/amount.js +36 -0
  9. package/amount.js.map +1 -0
  10. package/app-client.d.ts +14 -0
  11. package/app-client.d.ts.map +1 -0
  12. package/app-client.js +19 -0
  13. package/app-client.js.map +1 -0
  14. package/app-deploy.d.ts +95 -0
  15. package/app-deploy.d.ts.map +1 -0
  16. package/{deploy-app.js → app-deploy.js} +129 -119
  17. package/app-deploy.js.map +1 -0
  18. package/app.d.ts +112 -148
  19. package/app.d.ts.map +1 -1
  20. package/app.js +460 -143
  21. package/app.js.map +1 -1
  22. package/index.d.ts +6 -4
  23. package/index.d.ts.map +1 -1
  24. package/index.js +7 -4
  25. package/index.js.map +1 -1
  26. package/indexer-lookup.d.ts +11 -4
  27. package/indexer-lookup.d.ts.map +1 -1
  28. package/indexer-lookup.js +19 -9
  29. package/indexer-lookup.js.map +1 -1
  30. package/localnet.d.ts +10 -10
  31. package/localnet.d.ts.map +1 -1
  32. package/localnet.js +16 -16
  33. package/localnet.js.map +1 -1
  34. package/network-client.d.ts +15 -24
  35. package/network-client.d.ts.map +1 -1
  36. package/network-client.js +16 -16
  37. package/network-client.js.map +1 -1
  38. package/package.json +2 -2
  39. package/testing/account.d.ts +14 -0
  40. package/testing/account.d.ts.map +1 -0
  41. package/testing/account.js +31 -0
  42. package/testing/account.js.map +1 -0
  43. package/testing/fixtures/algokit-log-capture-fixture.d.ts +19 -0
  44. package/testing/fixtures/algokit-log-capture-fixture.d.ts.map +1 -0
  45. package/testing/fixtures/algokit-log-capture-fixture.js +43 -0
  46. package/testing/fixtures/algokit-log-capture-fixture.js.map +1 -0
  47. package/testing/fixtures/algorand-fixture.d.ts +24 -0
  48. package/testing/fixtures/algorand-fixture.d.ts.map +1 -0
  49. package/testing/fixtures/algorand-fixture.js +60 -0
  50. package/testing/fixtures/algorand-fixture.js.map +1 -0
  51. package/testing/fixtures/index.d.ts +3 -0
  52. package/testing/fixtures/index.d.ts.map +1 -0
  53. package/testing/fixtures/index.js +19 -0
  54. package/testing/fixtures/index.js.map +1 -0
  55. package/testing/index.d.ts +6 -0
  56. package/testing/index.d.ts.map +1 -0
  57. package/testing/index.js +22 -0
  58. package/testing/index.js.map +1 -0
  59. package/testing/indexer.d.ts +12 -0
  60. package/testing/indexer.d.ts.map +1 -0
  61. package/testing/indexer.js +40 -0
  62. package/testing/indexer.js.map +1 -0
  63. package/testing/test-logger.d.ts +41 -0
  64. package/testing/test-logger.d.ts.map +1 -0
  65. package/testing/test-logger.js +71 -0
  66. package/testing/test-logger.js.map +1 -0
  67. package/testing/transaction-logger.d.ts +29 -0
  68. package/testing/transaction-logger.d.ts.map +1 -0
  69. package/testing/transaction-logger.js +71 -0
  70. package/testing/transaction-logger.js.map +1 -0
  71. package/transaction.d.ts +55 -91
  72. package/transaction.d.ts.map +1 -1
  73. package/transaction.js +213 -155
  74. package/transaction.js.map +1 -1
  75. package/transfer.d.ts +14 -16
  76. package/transfer.d.ts.map +1 -1
  77. package/transfer.js +38 -4
  78. package/transfer.js.map +1 -1
  79. package/types/account.d.ts +55 -0
  80. package/types/account.d.ts.map +1 -0
  81. package/types/account.js +91 -0
  82. package/types/account.js.map +1 -0
  83. package/types/algo-http-client-with-retry.d.ts.map +1 -0
  84. package/{algo-http-client-with-retry.js → types/algo-http-client-with-retry.js} +3 -3
  85. package/types/algo-http-client-with-retry.js.map +1 -0
  86. package/types/algod.d.ts +28 -15
  87. package/types/algod.d.ts.map +1 -1
  88. package/{algo-amount.d.ts → types/amount.d.ts} +9 -3
  89. package/types/amount.d.ts.map +1 -0
  90. package/{algo-amount.js → types/amount.js} +13 -3
  91. package/types/amount.js.map +1 -0
  92. package/types/app-client.d.ts +282 -0
  93. package/types/app-client.d.ts.map +1 -0
  94. package/types/app-client.js +529 -0
  95. package/types/app-client.js.map +1 -0
  96. package/types/app-spec.d.ts +141 -0
  97. package/types/app-spec.d.ts.map +1 -0
  98. package/types/{appspec.js → app-spec.js} +5 -7
  99. package/types/app-spec.js.map +1 -0
  100. package/types/app.d.ts +285 -0
  101. package/types/app.d.ts.map +1 -0
  102. package/types/app.js +32 -0
  103. package/types/app.js.map +1 -0
  104. package/types/config.d.ts +32 -0
  105. package/types/config.d.ts.map +1 -0
  106. package/types/config.js +53 -0
  107. package/types/config.js.map +1 -0
  108. package/types/indexer.d.ts +368 -58
  109. package/types/indexer.d.ts.map +1 -1
  110. package/types/indexer.js +9 -0
  111. package/types/indexer.js.map +1 -1
  112. package/{config.d.ts → types/logging.d.ts} +2 -16
  113. package/types/logging.d.ts.map +1 -0
  114. package/{config.js → types/logging.js} +5 -24
  115. package/types/logging.js.map +1 -0
  116. package/types/logic-error.d.ts +37 -0
  117. package/types/logic-error.d.ts.map +1 -0
  118. package/types/logic-error.js +50 -0
  119. package/types/logic-error.js.map +1 -0
  120. package/types/network-client.d.ts +11 -0
  121. package/types/network-client.d.ts.map +1 -0
  122. package/types/network-client.js +3 -0
  123. package/types/network-client.js.map +1 -0
  124. package/types/testing.d.ts +89 -0
  125. package/types/testing.d.ts.map +1 -0
  126. package/types/testing.js +3 -0
  127. package/types/testing.js.map +1 -0
  128. package/types/transaction.d.ts +112 -0
  129. package/types/transaction.d.ts.map +1 -0
  130. package/types/transaction.js +3 -0
  131. package/types/transaction.js.map +1 -0
  132. package/types/transfer.d.ts +32 -0
  133. package/types/transfer.d.ts.map +1 -0
  134. package/types/transfer.js +3 -0
  135. package/types/transfer.js.map +1 -0
  136. package/types/urlTokenBaseHTTPClient.d.ts.map +1 -0
  137. package/types/urlTokenBaseHTTPClient.js.map +1 -0
  138. package/algo-amount.d.ts.map +0 -1
  139. package/algo-amount.js.map +0 -1
  140. package/algo-http-client-with-retry.d.ts.map +0 -1
  141. package/algo-http-client-with-retry.js.map +0 -1
  142. package/application-client.d.ts +0 -113
  143. package/application-client.d.ts.map +0 -1
  144. package/application-client.js +0 -258
  145. package/application-client.js.map +0 -1
  146. package/config.d.ts.map +0 -1
  147. package/config.js.map +0 -1
  148. package/deploy-app.d.ts +0 -164
  149. package/deploy-app.d.ts.map +0 -1
  150. package/deploy-app.js.map +0 -1
  151. package/types/appspec.d.ts +0 -78
  152. package/types/appspec.d.ts.map +0 -1
  153. package/types/appspec.js.map +0 -1
  154. package/urlTokenBaseHTTPClient.d.ts.map +0 -1
  155. package/urlTokenBaseHTTPClient.js.map +0 -1
  156. /package/{algo-http-client-with-retry.d.ts → types/algo-http-client-with-retry.d.ts} +0 -0
  157. /package/{urlTokenBaseHTTPClient.d.ts → types/urlTokenBaseHTTPClient.d.ts} +0 -0
  158. /package/{urlTokenBaseHTTPClient.js → types/urlTokenBaseHTTPClient.js} +0 -0
package/app.js CHANGED
@@ -23,15 +23,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.compileTeal = exports.getAppByIndex = exports.getAppArgsForTransaction = exports.getABIReturn = exports.callApp = exports.updateApp = exports.createApp = exports.ABI_RETURN_PREFIX = exports.APP_PAGE_MAX_SIZE = void 0;
26
+ exports.getABIMethodSignature = exports.compileTeal = exports.getAppByIndex = exports.getAppById = exports.getBoxReference = exports.getAppArgsForABICall = exports.getAppArgsForTransaction = exports.decodeAppState = exports.getAppBoxValuesFromABIType = exports.getAppBoxValueFromABIType = exports.getAppBoxValues = exports.getAppBoxValue = exports.getAppBoxNames = exports.getAppLocalState = exports.getAppGlobalState = exports.getABIReturn = exports.callApp = exports.updateApp = exports.createApp = void 0;
27
27
  const algosdk_1 = __importStar(require("algosdk"));
28
28
  const buffer_1 = require("buffer");
29
- const config_1 = require("./config");
29
+ const _1 = require("./");
30
30
  const transaction_1 = require("./transaction");
31
- /** The maximum number of bytes in an app code page */
32
- exports.APP_PAGE_MAX_SIZE = 2048;
33
- /** First 4 bytes of SHA-512/256 hash of "return" */
34
- exports.ABI_RETURN_PREFIX = new Uint8Array([21, 31, 124, 117]);
31
+ const app_1 = require("./types/app");
35
32
  /**
36
33
  * Creates a smart contract app, returns the details of the created app.
37
34
  * @param create The parameters to create the app with
@@ -40,38 +37,106 @@ exports.ABI_RETURN_PREFIX = new Uint8Array([21, 31, 124, 117]);
40
37
  */
41
38
  async function createApp(create, algod) {
42
39
  const { from, approvalProgram: approval, clearStateProgram: clear, schema, note, transactionParams, args, ...sendParams } = create;
43
- const approvalProgram = typeof approval === 'string' ? (await compileTeal(approval, algod)).compiledBase64ToBytes : approval;
44
- const clearProgram = typeof clear === 'string' ? (await compileTeal(clear, algod)).compiledBase64ToBytes : clear;
45
- const transaction = algosdk_1.default.makeApplicationCreateTxnFromObject({
46
- approvalProgram: approvalProgram,
47
- clearProgram: clearProgram,
48
- numLocalInts: schema.localInts,
49
- numLocalByteSlices: schema.localByteSlices,
50
- numGlobalInts: schema.globalInts,
51
- numGlobalByteSlices: schema.globalByteSlices,
52
- extraPages: schema.extraPages ?? Math.floor((approvalProgram.length + clearProgram.length) / exports.APP_PAGE_MAX_SIZE),
53
- onComplete: algosdk_1.default.OnApplicationComplete.NoOpOC,
54
- suggestedParams: await (0, transaction_1.getTransactionParams)(transactionParams, algod),
55
- from: (0, transaction_1.getSenderAddress)(from),
56
- note: (0, transaction_1.encodeTransactionNote)(note),
57
- ...getAppArgsForTransaction(args),
58
- rekeyTo: undefined,
59
- });
60
- const { confirmation } = await (0, transaction_1.sendTransaction)({ transaction, from, sendParams }, algod);
61
- if (confirmation) {
62
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
63
- const appIndex = confirmation['application-index'];
64
- config_1.AlgoKitConfig.getLogger(sendParams.suppressLog).debug(`Created app ${appIndex} from creator ${(0, transaction_1.getSenderAddress)(from)}`);
65
- return {
66
- transaction,
67
- confirmation,
68
- appIndex,
69
- appAddress: algosdk_1.default.getApplicationAddress(appIndex),
70
- return: getABIReturn(args, confirmation),
71
- };
40
+ const compiledApproval = typeof approval === 'string' ? await compileTeal(approval, algod) : undefined;
41
+ const approvalProgram = compiledApproval ? compiledApproval.compiledBase64ToBytes : approval;
42
+ const compiledClear = typeof clear === 'string' ? await compileTeal(clear, algod) : undefined;
43
+ const clearProgram = compiledClear ? compiledClear.compiledBase64ToBytes : clear;
44
+ if (args && 'method' in args) {
45
+ const atc = attachATC(sendParams);
46
+ const before = (0, transaction_1.getAtomicTransactionComposerTransactions)(atc);
47
+ atc.addMethodCall({
48
+ appID: 0,
49
+ approvalProgram: approvalProgram,
50
+ clearProgram: clearProgram,
51
+ numLocalInts: schema.localInts,
52
+ numLocalByteSlices: schema.localByteSlices,
53
+ numGlobalInts: schema.globalInts,
54
+ numGlobalByteSlices: schema.globalByteSlices,
55
+ extraPages: schema.extraPages ?? Math.floor((approvalProgram.length + clearProgram.length) / app_1.APP_PAGE_MAX_SIZE),
56
+ onComplete: algosdk_1.default.OnApplicationComplete.NoOpOC,
57
+ suggestedParams: (0, transaction_1.controlFees)(await (0, transaction_1.getTransactionParams)(transactionParams, algod), sendParams),
58
+ note: (0, transaction_1.encodeTransactionNote)(note),
59
+ ...(await getAppArgsForABICall(args, from)),
60
+ });
61
+ if (sendParams.skipSending) {
62
+ const after = atc.clone().buildGroup();
63
+ return {
64
+ transaction: after[after.length - 1].txn,
65
+ transactions: after.slice(before.length).map((t) => t.txn),
66
+ appId: 0,
67
+ appAddress: '',
68
+ compiledApproval,
69
+ compiledClear,
70
+ };
71
+ }
72
+ const result = await (0, transaction_1.sendAtomicTransactionComposer)({ atc, sendParams }, algod);
73
+ const confirmation = result.confirmations ? result.confirmations[result.confirmations?.length - 1] : undefined;
74
+ if (confirmation) {
75
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
76
+ const appId = confirmation['application-index'];
77
+ _1.Config.getLogger(sendParams.suppressLog).debug(`Created app ${appId} from creator ${(0, transaction_1.getSenderAddress)(from)}`);
78
+ return {
79
+ transactions: result.transactions,
80
+ confirmations: result.confirmations,
81
+ return: confirmation ? getABIReturn(args, confirmation) : undefined,
82
+ transaction: result.transactions[result.transactions.length - 1],
83
+ confirmation: confirmation,
84
+ appId,
85
+ appAddress: algosdk_1.default.getApplicationAddress(appId),
86
+ compiledApproval,
87
+ compiledClear,
88
+ };
89
+ }
90
+ else {
91
+ return {
92
+ transactions: result.transactions,
93
+ confirmations: result.confirmations,
94
+ return: confirmation ? getABIReturn(args, confirmation) : undefined,
95
+ transaction: result.transactions[result.transactions.length - 1],
96
+ confirmation: confirmation,
97
+ appId: 0,
98
+ appAddress: '',
99
+ compiledApproval,
100
+ compiledClear,
101
+ };
102
+ }
72
103
  }
73
104
  else {
74
- return { transaction, appIndex: 0, appAddress: '' };
105
+ const transaction = algosdk_1.default.makeApplicationCreateTxnFromObject({
106
+ approvalProgram: approvalProgram,
107
+ clearProgram: clearProgram,
108
+ numLocalInts: schema.localInts,
109
+ numLocalByteSlices: schema.localByteSlices,
110
+ numGlobalInts: schema.globalInts,
111
+ numGlobalByteSlices: schema.globalByteSlices,
112
+ extraPages: schema.extraPages ?? Math.floor((approvalProgram.length + clearProgram.length) / app_1.APP_PAGE_MAX_SIZE),
113
+ onComplete: algosdk_1.default.OnApplicationComplete.NoOpOC,
114
+ suggestedParams: await (0, transaction_1.getTransactionParams)(transactionParams, algod),
115
+ from: (0, transaction_1.getSenderAddress)(from),
116
+ note: (0, transaction_1.encodeTransactionNote)(note),
117
+ ...getAppArgsForTransaction(args),
118
+ rekeyTo: undefined,
119
+ });
120
+ const { confirmation } = await (0, transaction_1.sendTransaction)({ transaction, from, sendParams }, algod);
121
+ if (confirmation) {
122
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
123
+ const appId = confirmation['application-index'];
124
+ _1.Config.getLogger(sendParams.suppressLog).debug(`Created app ${appId} from creator ${(0, transaction_1.getSenderAddress)(from)}`);
125
+ return {
126
+ transaction,
127
+ transactions: [transaction],
128
+ confirmation,
129
+ confirmations: confirmation ? [confirmation] : undefined,
130
+ appId,
131
+ appAddress: algosdk_1.default.getApplicationAddress(appId),
132
+ return: getABIReturn(args, confirmation),
133
+ compiledApproval,
134
+ compiledClear,
135
+ };
136
+ }
137
+ else {
138
+ return { transaction, transactions: [transaction], appId: 0, appAddress: '', compiledApproval, compiledClear };
139
+ }
75
140
  }
76
141
  }
77
142
  exports.createApp = createApp;
@@ -82,27 +147,71 @@ exports.createApp = createApp;
82
147
  * @returns The transaction
83
148
  */
84
149
  async function updateApp(update, algod) {
85
- const { appIndex, from, approvalProgram: approval, clearStateProgram: clear, note, transactionParams, args, ...sendParams } = update;
86
- const approvalProgram = typeof approval === 'string' ? (await compileTeal(approval, algod)).compiledBase64ToBytes : approval;
87
- const clearProgram = typeof clear === 'string' ? (await compileTeal(clear, algod)).compiledBase64ToBytes : clear;
88
- const transaction = algosdk_1.default.makeApplicationUpdateTxnFromObject({
89
- appIndex,
90
- approvalProgram: approvalProgram,
91
- clearProgram: clearProgram,
92
- suggestedParams: await (0, transaction_1.getTransactionParams)(transactionParams, algod),
93
- from: (0, transaction_1.getSenderAddress)(from),
94
- note: (0, transaction_1.encodeTransactionNote)(note),
95
- ...getAppArgsForTransaction(args),
96
- rekeyTo: undefined,
97
- });
98
- config_1.AlgoKitConfig.getLogger(sendParams.suppressLog).debug(`Updating app ${appIndex}`);
99
- const result = await (0, transaction_1.sendTransaction)({ transaction, from, sendParams }, algod);
100
- return {
101
- ...result,
102
- return: getABIReturn(args, result.confirmation),
103
- };
150
+ const { appId, from, approvalProgram: approval, clearStateProgram: clear, note, transactionParams, args, ...sendParams } = update;
151
+ const compiledApproval = typeof approval === 'string' ? await compileTeal(approval, algod) : undefined;
152
+ const approvalProgram = compiledApproval ? compiledApproval.compiledBase64ToBytes : approval;
153
+ const compiledClear = typeof clear === 'string' ? await compileTeal(clear, algod) : undefined;
154
+ const clearProgram = compiledClear ? compiledClear.compiledBase64ToBytes : clear;
155
+ _1.Config.getLogger(sendParams.suppressLog).debug(`Updating app ${appId}`);
156
+ if (args && 'method' in args) {
157
+ const atc = attachATC(sendParams);
158
+ const before = (0, transaction_1.getAtomicTransactionComposerTransactions)(atc);
159
+ atc.addMethodCall({
160
+ appID: appId,
161
+ onComplete: algosdk_1.OnApplicationComplete.UpdateApplicationOC,
162
+ approvalProgram: approvalProgram,
163
+ clearProgram: clearProgram,
164
+ suggestedParams: (0, transaction_1.controlFees)(await (0, transaction_1.getTransactionParams)(transactionParams, algod), sendParams),
165
+ note: (0, transaction_1.encodeTransactionNote)(note),
166
+ ...(await getAppArgsForABICall(args, from)),
167
+ });
168
+ if (sendParams.skipSending) {
169
+ const after = atc.clone().buildGroup();
170
+ return {
171
+ transaction: after[after.length - 1].txn,
172
+ transactions: after.slice(before.length).map((t) => t.txn),
173
+ };
174
+ }
175
+ const result = await (0, transaction_1.sendAtomicTransactionComposer)({ atc, sendParams }, algod);
176
+ const confirmation = result.confirmations ? result.confirmations[result.confirmations?.length - 1] : undefined;
177
+ return {
178
+ transactions: result.transactions,
179
+ confirmations: result.confirmations,
180
+ return: confirmation ? getABIReturn(args, confirmation) : undefined,
181
+ transaction: result.transactions[result.transactions.length - 1],
182
+ confirmation: confirmation,
183
+ };
184
+ }
185
+ else {
186
+ const transaction = algosdk_1.default.makeApplicationUpdateTxnFromObject({
187
+ appIndex: appId,
188
+ approvalProgram: approvalProgram,
189
+ clearProgram: clearProgram,
190
+ suggestedParams: await (0, transaction_1.getTransactionParams)(transactionParams, algod),
191
+ from: (0, transaction_1.getSenderAddress)(from),
192
+ note: (0, transaction_1.encodeTransactionNote)(note),
193
+ ...getAppArgsForTransaction(args),
194
+ rekeyTo: undefined,
195
+ });
196
+ const result = await (0, transaction_1.sendTransaction)({ transaction, from, sendParams }, algod);
197
+ return {
198
+ ...result,
199
+ transactions: [result.transaction],
200
+ confirmations: result.confirmation ? [result.confirmation] : undefined,
201
+ return: getABIReturn(args, result.confirmation),
202
+ compiledApproval,
203
+ compiledClear,
204
+ };
205
+ }
104
206
  }
105
207
  exports.updateApp = updateApp;
208
+ function attachATC(sendParams) {
209
+ if (sendParams.atc) {
210
+ sendParams.skipSending = true;
211
+ }
212
+ sendParams.atc = sendParams.atc ?? new algosdk_1.AtomicTransactionComposer();
213
+ return sendParams.atc;
214
+ }
106
215
  /**
107
216
  * Issues a call to a given app.
108
217
  * @param call The call details.
@@ -110,9 +219,44 @@ exports.updateApp = updateApp;
110
219
  * @returns The result of the call
111
220
  */
112
221
  async function callApp(call, algod) {
113
- const { appIndex, callType, from, args, note, transactionParams, ...sendParams } = call;
114
- const appCallParameters = {
115
- appIndex: appIndex,
222
+ const { appId, callType, from, args, note, transactionParams, ...sendParams } = call;
223
+ if (args && 'method' in args) {
224
+ const atc = attachATC(sendParams);
225
+ const before = (0, transaction_1.getAtomicTransactionComposerTransactions)(atc);
226
+ atc.addMethodCall({
227
+ appID: appId,
228
+ suggestedParams: (0, transaction_1.controlFees)(await (0, transaction_1.getTransactionParams)(transactionParams, algod), sendParams),
229
+ note: (0, transaction_1.encodeTransactionNote)(note),
230
+ onComplete: callType === 'normal'
231
+ ? algosdk_1.OnApplicationComplete.NoOpOC
232
+ : callType === 'clearstate'
233
+ ? algosdk_1.OnApplicationComplete.ClearStateOC
234
+ : callType === 'closeout'
235
+ ? algosdk_1.OnApplicationComplete.CloseOutOC
236
+ : callType === 'delete'
237
+ ? algosdk_1.OnApplicationComplete.DeleteApplicationOC
238
+ : algosdk_1.OnApplicationComplete.OptInOC,
239
+ ...(await getAppArgsForABICall(args, from)),
240
+ });
241
+ if (sendParams.skipSending) {
242
+ const after = atc.clone().buildGroup();
243
+ return {
244
+ transaction: after[after.length - 1].txn,
245
+ transactions: after.slice(before.length).map((t) => t.txn),
246
+ };
247
+ }
248
+ const result = await (0, transaction_1.sendAtomicTransactionComposer)({ atc, sendParams }, algod);
249
+ const confirmation = result.confirmations ? result.confirmations[result.confirmations?.length - 1] : undefined;
250
+ return {
251
+ transactions: result.transactions,
252
+ confirmations: result.confirmations,
253
+ return: confirmation ? getABIReturn(args, confirmation) : undefined,
254
+ transaction: result.transactions[result.transactions.length - 1],
255
+ confirmation: confirmation,
256
+ };
257
+ }
258
+ const appCallParams = {
259
+ appIndex: appId,
116
260
  from: (0, transaction_1.getSenderAddress)(from),
117
261
  suggestedParams: await (0, transaction_1.getTransactionParams)(transactionParams, algod),
118
262
  ...getAppArgsForTransaction(args),
@@ -122,144 +266,317 @@ async function callApp(call, algod) {
122
266
  let transaction;
123
267
  switch (callType) {
124
268
  case 'optin':
125
- transaction = algosdk_1.default.makeApplicationOptInTxnFromObject(appCallParameters);
269
+ transaction = algosdk_1.default.makeApplicationOptInTxnFromObject(appCallParams);
126
270
  break;
127
271
  case 'clearstate':
128
- transaction = algosdk_1.default.makeApplicationClearStateTxnFromObject(appCallParameters);
272
+ transaction = algosdk_1.default.makeApplicationClearStateTxnFromObject(appCallParams);
129
273
  break;
130
274
  case 'closeout':
131
- transaction = algosdk_1.default.makeApplicationCloseOutTxnFromObject(appCallParameters);
275
+ transaction = algosdk_1.default.makeApplicationCloseOutTxnFromObject(appCallParams);
132
276
  break;
133
277
  case 'delete':
134
- transaction = algosdk_1.default.makeApplicationDeleteTxnFromObject(appCallParameters);
278
+ transaction = algosdk_1.default.makeApplicationDeleteTxnFromObject(appCallParams);
135
279
  break;
136
280
  case 'normal':
137
- transaction = algosdk_1.default.makeApplicationNoOpTxnFromObject(appCallParameters);
281
+ transaction = algosdk_1.default.makeApplicationNoOpTxnFromObject(appCallParams);
138
282
  break;
139
283
  }
140
284
  const result = await (0, transaction_1.sendTransaction)({ transaction, from, sendParams }, algod);
141
285
  return {
142
286
  ...result,
287
+ transactions: [result.transaction],
288
+ confirmations: result.confirmation ? [result.confirmation] : undefined,
143
289
  return: getABIReturn(args, result.confirmation),
144
290
  };
145
291
  }
146
292
  exports.callApp = callApp;
293
+ /**
294
+ * Returns any ABI return values for the given app call arguments and transaction confirmation.
295
+ * @param args The arguments that were used for the call
296
+ * @param confirmation The transaction confirmation from algod
297
+ * @returns The return value for the method call
298
+ */
147
299
  function getABIReturn(args, confirmation) {
148
- try {
149
- if (!args || !('method' in args)) {
150
- return undefined;
151
- }
152
- const method = 'txnCount' in args.method ? args.method : new algosdk_1.ABIMethod(args.method);
153
- if (method.returns.type !== 'void' && confirmation) {
154
- const logs = confirmation.logs || [];
155
- if (logs.length === 0) {
156
- throw new Error('App call transaction did not log a return value');
157
- }
158
- const lastLog = logs[logs.length - 1];
159
- if (lastLog.byteLength < 4 || lastLog.slice(0, 4).toString() !== exports.ABI_RETURN_PREFIX.toString()) {
160
- throw new Error('App call transaction did not log a return value (ABI_RETURN_PREFIX not found)');
161
- }
162
- return {
163
- rawReturnValue: new Uint8Array(lastLog.slice(4)),
164
- returnValue: method.returns.type.decode(new Uint8Array(lastLog.slice(4))),
300
+ if (!args || !('method' in args)) {
301
+ return undefined;
302
+ }
303
+ const method = 'txnCount' in args.method ? args.method : new algosdk_1.ABIMethod(args.method);
304
+ if (method.returns.type !== 'void' && confirmation) {
305
+ // The parseMethodResponse method mutates the second parameter :(
306
+ const resultDummy = {
307
+ txID: '',
308
+ method,
309
+ rawReturnValue: new Uint8Array(),
310
+ };
311
+ const response = algosdk_1.AtomicTransactionComposer.parseMethodResponse(method, resultDummy, confirmation);
312
+ return !response.decodeError
313
+ ? {
314
+ rawReturnValue: response.rawReturnValue,
315
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
316
+ returnValue: response.returnValue,
165
317
  decodeError: undefined,
318
+ }
319
+ : {
320
+ rawReturnValue: undefined,
321
+ returnValue: undefined,
322
+ decodeError: response.decodeError,
166
323
  };
167
- }
168
324
  }
169
- catch (e) {
325
+ return undefined;
326
+ }
327
+ exports.getABIReturn = getABIReturn;
328
+ /**
329
+ * Returns the current global state values for the given app ID
330
+ * @param appId The ID of the app return global state for
331
+ * @param algod An algod client instance
332
+ * @returns The current global state
333
+ */
334
+ async function getAppGlobalState(appId, algod) {
335
+ const appInfo = await getAppById(appId, algod);
336
+ if (!appInfo.params || !appInfo.params['global-state']) {
337
+ throw new Error("Couldn't find global state");
338
+ }
339
+ return decodeAppState(appInfo.params['global-state']);
340
+ }
341
+ exports.getAppGlobalState = getAppGlobalState;
342
+ /**
343
+ * Returns the current global state values for the given app ID and account
344
+ * @param appId The ID of the app return global state for
345
+ * @param account Either the string address of an account or an account object for the account to get local state for the given app
346
+ * @param algod An algod client instance
347
+ * @returns The current local state for the given (app, account) combination
348
+ */
349
+ async function getAppLocalState(appId, account, algod) {
350
+ const accountAddress = typeof account === 'string' ? account : (0, transaction_1.getSenderAddress)(account);
351
+ const appInfo = await algod.accountApplicationInformation(accountAddress, appId).do();
352
+ if (!appInfo['app-local-state'] || !appInfo['app-local-state']['key-value']) {
353
+ throw new Error("Couldn't find local state");
354
+ }
355
+ return decodeAppState(appInfo['app-local-state']['key-value']);
356
+ }
357
+ exports.getAppLocalState = getAppLocalState;
358
+ /**
359
+ * Returns the names of the boxes for the given app.
360
+ * @param appId The ID of the app return box names for
361
+ * @param algod An algod client instance
362
+ * @returns The current box names
363
+ */
364
+ async function getAppBoxNames(appId, algod) {
365
+ const boxResult = await algod.getApplicationBoxes(appId).do();
366
+ return boxResult.boxes.map((b) => {
170
367
  return {
171
- rawReturnValue: undefined,
172
- returnValue: undefined,
173
- decodeError: e,
368
+ nameRaw: b.name,
369
+ nameBase64: buffer_1.Buffer.from(b.name).toString('base64'),
370
+ name: buffer_1.Buffer.from(b.name).toString('utf-8'),
174
371
  };
372
+ });
373
+ }
374
+ exports.getAppBoxNames = getAppBoxNames;
375
+ /**
376
+ * Returns the value of the given box name for the given app.
377
+ * @param appId The ID of the app return box names for
378
+ * @param boxName The name of the box to return either as a string, binary array or `BoxName`
379
+ * @param algod An algod client instance
380
+ * @returns The current box value as a byte array
381
+ */
382
+ async function getAppBoxValue(appId, boxName, algod) {
383
+ const name = typeof boxName === 'string' ? new Uint8Array(buffer_1.Buffer.from(boxName, 'utf-8')) : 'name' in boxName ? boxName.nameRaw : boxName;
384
+ const boxResult = await algod.getApplicationBoxByName(appId, name).do();
385
+ return boxResult.value;
386
+ }
387
+ exports.getAppBoxValue = getAppBoxValue;
388
+ /**
389
+ * Returns the value of the given box names for the given app.
390
+ * @param appId The ID of the app return box names for
391
+ * @param boxNames The names of the boxes to return either as a string, binary array or `BoxName`
392
+ * @param algod An algod client instance
393
+ * @returns The current box values as a byte array in the same order as the passed in box names
394
+ */
395
+ async function getAppBoxValues(appId, boxNames, algod) {
396
+ return await Promise.all(boxNames.map(async (boxName) => await getAppBoxValue(appId, boxName, algod)));
397
+ }
398
+ exports.getAppBoxValues = getAppBoxValues;
399
+ /**
400
+ * Returns the value of the given box name for the given app decoded based on the given ABI type.
401
+ * @param request The parameters for the box value request
402
+ * @param algod An algod client instance
403
+ * @returns The current box value as an ABI value
404
+ */
405
+ async function getAppBoxValueFromABIType(request, algod) {
406
+ const { appId, boxName, type } = request;
407
+ const value = await getAppBoxValue(appId, boxName, algod);
408
+ return type.decode(value);
409
+ }
410
+ exports.getAppBoxValueFromABIType = getAppBoxValueFromABIType;
411
+ /**
412
+ * Returns the value of the given box names for the given app decoded based on the given ABI type.
413
+ * @param request The parameters for the box value request
414
+ * @param algod An algod client instance
415
+ * @returns The current box values as an ABI value in the same order as the passed in box names
416
+ */
417
+ async function getAppBoxValuesFromABIType(request, algod) {
418
+ const { appId, boxNames, type } = request;
419
+ return await Promise.all(boxNames.map(async (boxName) => await getAppBoxValueFromABIType({ appId, boxName, type }, algod)));
420
+ }
421
+ exports.getAppBoxValuesFromABIType = getAppBoxValuesFromABIType;
422
+ /**
423
+ * Converts an array of global/local state values from the algod api to a more friendly
424
+ * generic object keyed by the UTF-8 value of the key.
425
+ * @param state A `global-state`, `local-state`, `global-state-deltas` or `local-state-deltas`
426
+ * @returns An object keyeed by the UTF-8 representation of the key with various parsings of the values
427
+ */
428
+ function decodeAppState(state) {
429
+ const stateValues = {};
430
+ // Start with empty set
431
+ for (const stateVal of state) {
432
+ const keyBase64 = stateVal.key;
433
+ const keyRaw = buffer_1.Buffer.from(keyBase64, 'base64');
434
+ const key = keyRaw.toString('utf-8');
435
+ const tealValue = stateVal.value;
436
+ const dataTypeFlag = 'action' in tealValue ? tealValue.action : tealValue.type;
437
+ let valueBase64;
438
+ let valueRaw;
439
+ switch (dataTypeFlag) {
440
+ case 1:
441
+ valueBase64 = 'bytes' in tealValue ? tealValue.bytes : '';
442
+ valueRaw = buffer_1.Buffer.from(valueBase64, 'base64');
443
+ stateValues[key] = {
444
+ keyRaw,
445
+ keyBase64,
446
+ valueRaw: new Uint8Array(valueRaw),
447
+ valueBase64: valueBase64,
448
+ value: valueRaw.toString('utf-8'),
449
+ };
450
+ break;
451
+ case 2:
452
+ // eslint-disable-next-line no-case-declarations
453
+ const value = 'uint' in tealValue ? tealValue.uint : 0;
454
+ stateValues[key] = {
455
+ keyRaw,
456
+ keyBase64,
457
+ value,
458
+ };
459
+ break;
460
+ default:
461
+ throw new Error(`Received unknown state data type of ${dataTypeFlag}`);
462
+ }
175
463
  }
176
- return undefined;
464
+ return stateValues;
177
465
  }
178
- exports.getABIReturn = getABIReturn;
179
- /** Returns the app args ready to load onto an app @see {Transaction} object */
466
+ exports.decodeAppState = decodeAppState;
467
+ /**
468
+ * Returns the app args ready to load onto an app `Transaction` object
469
+ * @param args The app call args
470
+ * @returns The args ready to load into a `Transaction`
471
+ */
180
472
  function getAppArgsForTransaction(args) {
181
473
  if (!args)
182
474
  return undefined;
183
- let actualArgs;
184
- if ('method' in args) {
185
- // todo: Land a change to algosdk that extract the logic from ATC, because (fair warning) this is a HACK
186
- // I don't want to have to rewrite all of the ABI resolution logic so using an ATC temporarily here
187
- // and passing stuff in to keep it happy like a randomly generated account :O
188
- // Most of these values aren't being used since the transaction is discarded
189
- const dummyAtc = new algosdk_1.AtomicTransactionComposer();
190
- const dummyAccount = algosdk_1.default.generateAccount();
191
- const dummyAppId = 1;
192
- const dummyParams = {
193
- fee: 1,
194
- firstRound: 1,
195
- genesisHash: buffer_1.Buffer.from('abcd', 'utf-8').toString('base64'),
196
- genesisID: 'a',
197
- lastRound: 1,
198
- };
199
- const dummyOnComplete = algosdk_1.OnApplicationComplete.NoOpOC;
200
- dummyAtc.addMethodCall({
201
- method: 'txnCount' in args.method ? args.method : new algosdk_1.ABIMethod(args.method),
202
- methodArgs: args.args,
203
- // Rest are dummy values
204
- appID: dummyAppId,
205
- sender: dummyAccount.addr,
206
- signer: (0, algosdk_1.makeBasicAccountTransactionSigner)(dummyAccount),
207
- suggestedParams: dummyParams,
208
- onComplete: dummyOnComplete,
209
- });
210
- const txn = dummyAtc.buildGroup()[0];
211
- actualArgs = {
212
- accounts: txn.txn.appAccounts,
213
- appArgs: txn.txn.appArgs,
214
- apps: txn.txn.appForeignApps,
215
- assets: txn.txn.appForeignAssets,
216
- boxes: txn.txn.boxes,
217
- lease: args.lease,
218
- };
219
- }
220
- else {
221
- actualArgs = args;
222
- }
223
475
  const encoder = new TextEncoder();
224
476
  return {
225
- accounts: actualArgs?.accounts?.map((a) => (typeof a === 'string' ? a : algosdk_1.default.encodeAddress(a.publicKey))),
226
- appArgs: actualArgs?.appArgs?.map((a) => (typeof a === 'string' ? encoder.encode(a) : a)),
227
- boxes: actualArgs?.boxes?.map((ref) => ({
228
- appIndex: ref.appIndex,
229
- name: typeof ref.name === 'string' ? encoder.encode(ref.name) : ref.name,
230
- })),
231
- foreignApps: actualArgs?.apps,
232
- foreignAssets: actualArgs?.assets,
233
- lease: typeof actualArgs?.lease === 'string' ? encoder.encode(actualArgs?.lease) : actualArgs?.lease,
477
+ accounts: args?.accounts?.map((a) => (typeof a === 'string' ? a : algosdk_1.default.encodeAddress(a.publicKey))),
478
+ appArgs: args?.appArgs?.map((a) => (typeof a === 'string' ? encoder.encode(a) : a)),
479
+ boxes: args.boxes?.map(getBoxReference),
480
+ foreignApps: args?.apps,
481
+ foreignAssets: args?.assets,
482
+ lease: typeof args?.lease === 'string' ? encoder.encode(args?.lease) : args?.lease,
234
483
  };
235
484
  }
236
485
  exports.getAppArgsForTransaction = getAppArgsForTransaction;
486
+ /**
487
+ * Returns the app args ready to load onto an ABI method call in `AtomicTransactionComposer`
488
+ * @param args The ABI app call args
489
+ * @param from The transaction signer
490
+ * @returns The parameters ready to pass into `addMethodCall` within AtomicTransactionComposer
491
+ */
492
+ async function getAppArgsForABICall(args, from) {
493
+ const encoder = new TextEncoder();
494
+ const signer = (0, transaction_1.getSenderTransactionSigner)(from);
495
+ const methodArgs = await Promise.all(args.args?.map(async (a) => {
496
+ if (typeof a !== 'object') {
497
+ return a;
498
+ }
499
+ // Handle the various forms of transactions to wrangle them for ATC
500
+ return 'txn' in a
501
+ ? a
502
+ : 'then' in a
503
+ ? { txn: (await a).transaction, signer }
504
+ : 'transaction' in a
505
+ ? { txn: a.transaction, signer }
506
+ : 'txID' in a
507
+ ? { txn: a, signer }
508
+ : a;
509
+ }));
510
+ return {
511
+ method: 'txnCount' in args.method ? args.method : new algosdk_1.ABIMethod(args.method),
512
+ sender: (0, transaction_1.getSenderAddress)(from),
513
+ signer: signer,
514
+ boxes: args.boxes?.map(getBoxReference),
515
+ lease: typeof args.lease === 'string' ? encoder.encode(args.lease) : args.lease,
516
+ methodArgs: methodArgs,
517
+ rekeyTo: undefined,
518
+ };
519
+ }
520
+ exports.getAppArgsForABICall = getAppArgsForABICall;
521
+ /**
522
+ * Returns a `algosdk.BoxReference` given a `BoxIdentifier` or `BoxReference`.
523
+ * @param box The box to return a reference for
524
+ * @returns The box reference ready to pass into a `Transaction`
525
+ */
526
+ function getBoxReference(box) {
527
+ const encoder = new TextEncoder();
528
+ if (typeof box === 'object' && 'appIndex' in box) {
529
+ return box;
530
+ }
531
+ const ref = typeof box === 'object' && 'appId' in box ? box : { appId: 0, name: box };
532
+ return {
533
+ appIndex: ref.appId,
534
+ name: typeof ref.name === 'string'
535
+ ? encoder.encode(ref.name)
536
+ : 'length' in ref.name
537
+ ? ref.name
538
+ : algosdk_1.default.decodeAddress((0, transaction_1.getSenderAddress)(ref.name)).publicKey,
539
+ };
540
+ }
541
+ exports.getBoxReference = getBoxReference;
237
542
  /**
238
543
  * Gets the current data for the given app from algod.
239
544
  *
240
- * @param appIndex The index of the app
545
+ * @param appId The id of the app
241
546
  * @param algod An algod client
242
547
  * @returns The data about the app
243
548
  */
244
- async function getAppByIndex(appIndex, algod) {
245
- return (await algod.getApplicationByID(appIndex).do());
549
+ async function getAppById(appId, algod) {
550
+ return (await algod.getApplicationByID(appId).do());
246
551
  }
247
- exports.getAppByIndex = getAppByIndex;
552
+ exports.getAppById = getAppById;
553
+ /** @deprecated Use `algokit.getAppById` instead. */
554
+ exports.getAppByIndex = getAppById;
248
555
  /**
249
- * Compiles the given TEAL using algod and returns the result.
556
+ * Compiles the given TEAL using algod and returns the result, including source map.
250
557
  *
251
558
  * @param algod An algod client
252
559
  * @param tealCode The TEAL code
253
560
  * @returns The information about the compiled file
254
561
  */
255
562
  async function compileTeal(tealCode, algod) {
256
- const compiled = await algod.compile(tealCode).do();
563
+ const compiled = await algod.compile(tealCode).sourcemap(true).do();
257
564
  return {
258
565
  teal: tealCode,
259
566
  compiled: compiled.result,
260
567
  compiledHash: compiled.hash,
261
568
  compiledBase64ToBytes: new Uint8Array(buffer_1.Buffer.from(compiled.result, 'base64')),
569
+ sourceMap: new algosdk_1.SourceMap(compiled['sourcemap']),
262
570
  };
263
571
  }
264
572
  exports.compileTeal = compileTeal;
573
+ /**
574
+ * Returns the encoded ABI spec for a given ABI Method
575
+ * @param method The method to return a signature for
576
+ * @returns The encoded ABI method spec e.g. `method_name(uint64,string)string`
577
+ */
578
+ const getABIMethodSignature = (method) => {
579
+ return 'getSignature' in method ? method.getSignature() : new algosdk_1.ABIMethod(method).getSignature();
580
+ };
581
+ exports.getABIMethodSignature = getABIMethodSignature;
265
582
  //# sourceMappingURL=app.js.map