@algorandfoundation/algorand-typescript-testing 1.0.0-alpha.16 → 1.0.0-alpha.18

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.
package/encoders.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { internal } from '@algorandfoundation/algorand-typescript';
1
+ import { bytes, internal } from '@algorandfoundation/algorand-typescript';
2
2
  import { DeliberateAny } from './typescript-helpers';
3
3
  export type TypeInfo = {
4
4
  name: string;
@@ -7,3 +7,4 @@ export type TypeInfo = {
7
7
  export type fromBytes<T> = (val: Uint8Array | internal.primitives.StubBytesCompat, typeInfo: TypeInfo, prefix?: 'none' | 'log') => T;
8
8
  export declare const encoders: Record<string, fromBytes<DeliberateAny>>;
9
9
  export declare const getEncoder: <T>(typeInfo: TypeInfo) => fromBytes<T>;
10
+ export declare const toBytes: (val: unknown) => bytes;
@@ -0,0 +1,3 @@
1
+ import { assertMatch, match } from '@algorandfoundation/algorand-typescript';
2
+ export declare const matchImpl: typeof match;
3
+ export declare const assertMatchImpl: typeof assertMatch;
@@ -0,0 +1,2 @@
1
+ import { internal } from '@algorandfoundation/algorand-typescript';
2
+ export declare function urangeImpl(a: internal.primitives.StubUint64Compat, b?: internal.primitives.StubUint64Compat, c?: internal.primitives.StubUint64Compat): Generator<import("@algorandfoundation/algorand-typescript").uint64, number, unknown>;
package/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export { TestExecutionContext } from './test-execution-context';
2
+ export { asUint8Array as bytesToUint8Array } from './util';
package/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { Bytes, Uint64, Account, internal, Base64, op, arc4, TransactionType, Asset, Application, BigUint, BaseContract, Contract } from '@algorandfoundation/algorand-typescript';
2
- import { a as asMaybeUint64Cls, l as lazyContext, b as asUint64, c as asBytes, t as toBytes, d as asMaybeBytesCls, e as asBigUint, B as BITS_IN_BYTE, M as MAX_BYTES_SIZE, f as asUint64Cls, g as asBytesCls, h as testInvariant, i as MAX_UINT8, j as binaryStringToBytes, U as UINT64_SIZE, n as notImplementedError, k as MAX_UINT64, m as asNumber, o as MAX_BOX_SIZE, p as asUint8Array, q as conactUint8Arrays, r as getObjectReference, s as getApplicationAddress, u as MIN_TXN_FEE, D as DEFAULT_ACCOUNT_MIN_BALANCE, v as DEFAULT_MAX_TXN_LIFE, Z as ZERO_ADDRESS, w as DEFAULT_ASSET_CREATE_MIN_BALANCE, x as DEFAULT_ASSET_OPT_IN_MIN_BALANCE, y as DEFAULT_GLOBAL_GENESIS_HASH, E as EllipticCurve, z as ecdsaPkDecompress, A as ecdsaPkRecover, C as ecdsaVerify, F as ed25519verify, G as ed25519verifyBare, H as keccak256, I as sha256, J as sha3_256, K as sha512_256, L as vrfVerify, N as combineIntoMaxBytePages, O as MAX_ITEMS_IN_LOG, P as ABI_RETURN_VALUE_LOG_PREFIX, Q as getRandomBytes, R as getArc4Encoder, S as AccountCls, T as ApplicationCls, V as AssetCls, W as arc4Encoders, X as AccountMap, Y as getGenericTypeInfo, _ as getArc4Selector, $ as isContractProxy, a0 as getContractMethodAbiMetadata, a1 as copyAbiMetadatas, a2 as getContractAbiMetadata, a3 as BytesMap, a4 as iterBigInt, a5 as Uint64Map, a6 as AssetHolding$1, a7 as asBigInt, a8 as TRANSACTION_GROUP_MAX_SIZE, a9 as getRandomBigInt, aa as AccountData, ab as ApplicationData, ac as AddressImpl, ad as UintNImpl, ae as getRandomNumber, af as MAX_UINT16, ag as MAX_UINT32, ah as MAX_UINT128, ai as MAX_UINT256, aj as MAX_UINT512, ak as DynamicBytesImpl, al as StrImpl, am as captureMethodConfig, an as DEFAULT_TEMPLATE_VAR_PREFIX } from './runtime-helpers-qRDREJih.js';
1
+ import { Bytes, Uint64, Account, internal, BigUint, Base64, op, arc4, TransactionType, Asset, Application, BaseContract, Contract } from '@algorandfoundation/algorand-typescript';
2
+ import { a as asMaybeUint64Cls, l as lazyContext, b as asUint64, c as asMaybeBytesCls, d as asMaybeBigUintCls, B as BytesBackedCls, U as Uint64BackedCls, e as asUint64Cls, f as encodeArc4Impl, n as nameOfType, g as getArc4Encoder, A as AccountCls, h as ApplicationCls, i as AssetCls, j as arc4Encoders, k as asUint8Array, m as asBytes, o as asBigUint, p as BITS_IN_BYTE, M as MAX_BYTES_SIZE, q as asBytesCls, t as testInvariant, r as MAX_UINT8, s as binaryStringToBytes, u as UINT64_SIZE, v as notImplementedError, w as MAX_UINT64, x as asNumber, y as MAX_BOX_SIZE, z as conactUint8Arrays, C as getObjectReference, D as getApplicationAddress, E as MIN_TXN_FEE, F as DEFAULT_ACCOUNT_MIN_BALANCE, G as DEFAULT_MAX_TXN_LIFE, Z as ZERO_ADDRESS, H as DEFAULT_ASSET_CREATE_MIN_BALANCE, I as DEFAULT_ASSET_OPT_IN_MIN_BALANCE, J as DEFAULT_GLOBAL_GENESIS_HASH, K as EllipticCurve, L as ecdsaPkDecompress, N as ecdsaPkRecover, O as ecdsaVerify, P as ed25519verify, Q as ed25519verifyBare, R as keccak256, S as sha256, T as sha3_256, V as sha512_256, W as vrfVerify, X as combineIntoMaxBytePages, Y as MAX_ITEMS_IN_LOG, _ as ABI_RETURN_VALUE_LOG_PREFIX, $ as getRandomBytes, a0 as AccountMap, a1 as getGenericTypeInfo, a2 as getArc4Selector, a3 as isContractProxy, a4 as getContractMethodAbiMetadata, a5 as copyAbiMetadatas, a6 as getContractAbiMetadata, a7 as BytesMap, a8 as iterBigInt, a9 as Uint64Map, aa as AssetHolding$1, ab as asBigInt, ac as TRANSACTION_GROUP_MAX_SIZE, ad as getRandomBigInt, ae as AccountData, af as ApplicationData, ag as AddressImpl, ah as UintNImpl, ai as getRandomNumber, aj as MAX_UINT16, ak as MAX_UINT32, al as MAX_UINT128, am as MAX_UINT256, an as MAX_UINT512, ao as DynamicBytesImpl, ap as StrImpl, aq as captureMethodConfig, ar as DEFAULT_TEMPLATE_VAR_PREFIX } from './runtime-helpers-Dc0sRTs-.js';
3
+ import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4';
3
4
  import { randomBytes } from 'crypto';
4
- import '@algorandfoundation/algorand-typescript/arc4';
5
5
  import '@algorandfoundation/puya-ts';
6
6
  import 'js-sha512';
7
7
  import 'assert';
@@ -154,6 +154,71 @@ const AcctParams = {
154
154
  },
155
155
  };
156
156
 
157
+ const booleanFromBytes = (val) => {
158
+ return internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)) > 0n;
159
+ };
160
+ const bigUintFromBytes = (val) => {
161
+ return BigUint(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)));
162
+ };
163
+ const bytesFromBytes = (val) => {
164
+ return asBytes(val);
165
+ };
166
+ const stringFromBytes = (val) => {
167
+ return asBytes(val).toString();
168
+ };
169
+ const uint64FromBytes = (val) => {
170
+ return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)));
171
+ };
172
+ const onCompletionFromBytes = (val) => {
173
+ return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)));
174
+ };
175
+ const transactionTypeFromBytes = (val) => {
176
+ return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)));
177
+ };
178
+ const encoders = {
179
+ account: AccountCls.fromBytes,
180
+ application: ApplicationCls.fromBytes,
181
+ asset: AssetCls.fromBytes,
182
+ boolean: booleanFromBytes,
183
+ biguint: bigUintFromBytes,
184
+ bytes: bytesFromBytes,
185
+ string: stringFromBytes,
186
+ uint64: uint64FromBytes,
187
+ OnCompleteAction: onCompletionFromBytes,
188
+ TransactionType: transactionTypeFromBytes,
189
+ ...arc4Encoders,
190
+ };
191
+ const getEncoder = (typeInfo) => {
192
+ return getArc4Encoder(typeInfo, encoders);
193
+ };
194
+ const toBytes = (val) => {
195
+ const uint64Val = asMaybeUint64Cls(val);
196
+ if (uint64Val !== undefined) {
197
+ return uint64Val.toBytes().asAlgoTs();
198
+ }
199
+ const bytesVal = asMaybeBytesCls(val);
200
+ if (bytesVal !== undefined) {
201
+ return bytesVal.asAlgoTs();
202
+ }
203
+ const bigUintVal = asMaybeBigUintCls(val);
204
+ if (bigUintVal !== undefined) {
205
+ return bigUintVal.toBytes().asAlgoTs();
206
+ }
207
+ if (val instanceof BytesBackedCls) {
208
+ return val.bytes;
209
+ }
210
+ if (val instanceof Uint64BackedCls) {
211
+ return asUint64Cls(val.uint64).toBytes().asAlgoTs();
212
+ }
213
+ if (val instanceof ARC4Encoded) {
214
+ return val.bytes;
215
+ }
216
+ if (Array.isArray(val) || typeof val === 'object') {
217
+ return encodeArc4Impl('', val);
218
+ }
219
+ internal.errors.internalError(`Invalid type for bytes: ${nameOfType(val)}`);
220
+ };
221
+
157
222
  const AppGlobal = {
158
223
  delete(a) {
159
224
  lazyContext.ledger.setGlobalState(lazyContext.activeApplication, a, undefined);
@@ -2805,12 +2870,14 @@ class AssetConfigInnerTxn extends AssetConfigTransaction {
2805
2870
  /* @internal */
2806
2871
  constructor(fields) {
2807
2872
  const { assetName, unitName, url, ...rest } = mapCommonFields(fields);
2808
- const createdAsset = lazyContext.any.asset({
2809
- name: typeof assetName === 'string' ? asBytes(assetName) : assetName,
2810
- unitName: typeof unitName === 'string' ? asBytes(unitName) : unitName,
2811
- url: typeof url === 'string' ? asBytes(url) : url,
2812
- ...rest,
2813
- });
2873
+ const createdAsset = !rest.configAsset || !asNumber(rest.configAsset.id)
2874
+ ? lazyContext.any.asset({
2875
+ name: typeof assetName === 'string' ? asBytes(assetName) : assetName,
2876
+ unitName: typeof unitName === 'string' ? asBytes(unitName) : unitName,
2877
+ url: typeof url === 'string' ? asBytes(url) : url,
2878
+ ...rest,
2879
+ })
2880
+ : undefined;
2814
2881
  super({
2815
2882
  assetName: typeof assetName === 'string' ? asBytes(assetName) : assetName,
2816
2883
  unitName: typeof unitName === 'string' ? asBytes(unitName) : unitName,
@@ -2913,27 +2980,21 @@ function submitGroup(...transactionFields) {
2913
2980
  return transactionFields.map((f) => f.submit());
2914
2981
  }
2915
2982
  function payment(fields) {
2916
- ensureItxnGroupBegin();
2917
2983
  return new ItxnParams(fields, TransactionType.Payment);
2918
2984
  }
2919
2985
  function keyRegistration(fields) {
2920
- ensureItxnGroupBegin();
2921
2986
  return new ItxnParams(fields, TransactionType.KeyRegistration);
2922
2987
  }
2923
2988
  function assetConfig(fields) {
2924
- ensureItxnGroupBegin();
2925
2989
  return new ItxnParams(fields, TransactionType.AssetConfig);
2926
2990
  }
2927
2991
  function assetTransfer(fields) {
2928
- ensureItxnGroupBegin();
2929
2992
  return new ItxnParams(fields, TransactionType.AssetTransfer);
2930
2993
  }
2931
2994
  function assetFreeze(fields) {
2932
- ensureItxnGroupBegin();
2933
2995
  return new ItxnParams(fields, TransactionType.AssetFreeze);
2934
2996
  }
2935
2997
  function applicationCall(fields) {
2936
- ensureItxnGroupBegin();
2937
2998
  return new ItxnParams(fields, TransactionType.ApplicationCall);
2938
2999
  }
2939
3000
  class ItxnParams {
@@ -2942,7 +3003,9 @@ class ItxnParams {
2942
3003
  this.#fields = { ...fields, type };
2943
3004
  }
2944
3005
  submit() {
2945
- return createInnerTxn(this.#fields);
3006
+ const innerTxn = createInnerTxn(this.#fields);
3007
+ lazyContext.txn.activeGroup.addInnerTransactionGroup(innerTxn);
3008
+ return innerTxn;
2946
3009
  }
2947
3010
  set(p) {
2948
3011
  Object.assign(this.#fields, p);
@@ -2951,49 +3014,6 @@ class ItxnParams {
2951
3014
  return new ItxnParams(this.#fields, this.#fields.type);
2952
3015
  }
2953
3016
  }
2954
- const ensureItxnGroupBegin = () => {
2955
- if (!lazyContext.activeGroup.constructingItxnGroup.length) {
2956
- lazyContext.activeGroup.beginInnerTransactionGroup();
2957
- }
2958
- };
2959
-
2960
- const booleanFromBytes = (val) => {
2961
- return internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)) > 0n;
2962
- };
2963
- const bigUintFromBytes = (val) => {
2964
- return BigUint(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)));
2965
- };
2966
- const bytesFromBytes = (val) => {
2967
- return asBytes(val);
2968
- };
2969
- const stringFromBytes = (val) => {
2970
- return asBytes(val).toString();
2971
- };
2972
- const uint64FromBytes = (val) => {
2973
- return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)));
2974
- };
2975
- const onCompletionFromBytes = (val) => {
2976
- return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)));
2977
- };
2978
- const transactionTypeFromBytes = (val) => {
2979
- return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)));
2980
- };
2981
- const encoders = {
2982
- account: AccountCls.fromBytes,
2983
- application: ApplicationCls.fromBytes,
2984
- asset: AssetCls.fromBytes,
2985
- boolean: booleanFromBytes,
2986
- biguint: bigUintFromBytes,
2987
- bytes: bytesFromBytes,
2988
- string: stringFromBytes,
2989
- uint64: uint64FromBytes,
2990
- OnCompleteAction: onCompletionFromBytes,
2991
- TransactionType: transactionTypeFromBytes,
2992
- ...arc4Encoders,
2993
- };
2994
- const getEncoder = (typeInfo) => {
2995
- return getArc4Encoder(typeInfo, encoders);
2996
- };
2997
3017
 
2998
3018
  class GlobalStateCls {
2999
3019
  _type = GlobalStateCls.name;
@@ -3548,6 +3568,12 @@ class LedgerContext {
3548
3568
  addAppIdContractMap(appId, contract) {
3549
3569
  this.appIdContractMap.set(appId, contract);
3550
3570
  }
3571
+ getAccount(address) {
3572
+ if (this.accountDataMap.has(address)) {
3573
+ return Account(address.bytes);
3574
+ }
3575
+ throw internal.errors.internalError('Unknown account, check correct testing context is active');
3576
+ }
3551
3577
  getAsset(assetId) {
3552
3578
  if (this.assetDataMap.has(assetId)) {
3553
3579
  return Asset(asUint64(assetId));
@@ -3575,16 +3601,16 @@ class LedgerContext {
3575
3601
  return undefined;
3576
3602
  }
3577
3603
  const entries = this.applicationDataMap.entries();
3578
- let next = entries.next().value;
3604
+ let next = entries.next();
3579
3605
  let found = false;
3580
- while (next && !found) {
3581
- found = next[1].application.approvalProgram === approvalProgram;
3606
+ while (!next.done && !found) {
3607
+ found = next.value[1].application.approvalProgram === approvalProgram;
3582
3608
  if (!found) {
3583
- next = entries.next().value;
3609
+ next = entries.next();
3584
3610
  }
3585
3611
  }
3586
- if (found && next) {
3587
- const appId = asUint64(next[0]);
3612
+ if (found && next?.value) {
3613
+ const appId = asUint64(next.value[0]);
3588
3614
  if (this.applicationDataMap.has(appId)) {
3589
3615
  return Application(appId);
3590
3616
  }
@@ -3683,15 +3709,19 @@ class LedgerContext {
3683
3709
  }
3684
3710
  }
3685
3711
 
3712
+ const ABI_RETURN_VALUE_LOG_PREFIX_LENGTH = asNumber(ABI_RETURN_VALUE_LOG_PREFIX.length);
3686
3713
  function decodeLogs(logs, decoding) {
3687
3714
  return logs.map((log, i) => {
3715
+ const value = log.slice(0, ABI_RETURN_VALUE_LOG_PREFIX_LENGTH).equals(ABI_RETURN_VALUE_LOG_PREFIX)
3716
+ ? log.slice(ABI_RETURN_VALUE_LOG_PREFIX_LENGTH)
3717
+ : log;
3688
3718
  switch (decoding[i]) {
3689
3719
  case 'i':
3690
- return op.btoi(log);
3720
+ return op.btoi(value);
3691
3721
  case 's':
3692
- return log.toString();
3722
+ return value.toString();
3693
3723
  default:
3694
- return log;
3724
+ return value;
3695
3725
  }
3696
3726
  });
3697
3727
  }
@@ -3751,13 +3781,12 @@ class TransactionContext {
3751
3781
  createScope(group, activeTransactionIndex) {
3752
3782
  const transactions = group.map((t) => (t instanceof DeferredAppCall ? t.txns : [t])).flat();
3753
3783
  const transactionGroup = new TransactionGroup(transactions, activeTransactionIndex);
3754
- const previousGroup = this.#activeGroup;
3755
3784
  this.#activeGroup = transactionGroup;
3756
3785
  const scope = ScopeGenerator(() => {
3757
3786
  if (this.#activeGroup?.transactions?.length) {
3758
3787
  this.groups.push(this.#activeGroup);
3759
3788
  }
3760
- this.#activeGroup = previousGroup;
3789
+ this.#activeGroup = undefined;
3761
3790
  });
3762
3791
  return {
3763
3792
  execute: (body) => {
@@ -3862,6 +3891,9 @@ class TransactionGroup {
3862
3891
  const filteredFields = Object.fromEntries(Object.entries(fields).filter(([_, value]) => value !== undefined));
3863
3892
  Object.assign(activeTransaction, filteredFields);
3864
3893
  }
3894
+ addInnerTransactionGroup(...itxns) {
3895
+ this.itxnGroups.push(new ItxnGroup(itxns));
3896
+ }
3865
3897
  beginInnerTransactionGroup() {
3866
3898
  if (this.constructingItxnGroup.length) {
3867
3899
  internal.errors.internalError('itxn begin without itxn submit');
@@ -3890,6 +3922,9 @@ class TransactionGroup {
3890
3922
  this.itxnGroups.push(new ItxnGroup(itxns));
3891
3923
  this.constructingItxnGroup = [];
3892
3924
  }
3925
+ lastItxnGroup() {
3926
+ return this.getItxnGroup();
3927
+ }
3893
3928
  getItxnGroup(index) {
3894
3929
  const i = index !== undefined ? asNumber(index) : undefined;
3895
3930
  testInvariant(this.itxnGroups.length > 0, 'no previous inner transactions');
@@ -4011,20 +4046,30 @@ class ItxnGroup {
4011
4046
 
4012
4047
  class AvmValueGenerator {
4013
4048
  uint64(minValue = 0n, maxValue = MAX_UINT64) {
4014
- if (maxValue > MAX_UINT64) {
4049
+ const min = asBigInt(minValue);
4050
+ const max = asBigInt(maxValue);
4051
+ if (max > MAX_UINT64) {
4015
4052
  internal.errors.internalError('maxValue must be less than or equal to MAX_UINT64');
4016
4053
  }
4017
- if (minValue > maxValue) {
4054
+ if (min > max) {
4018
4055
  internal.errors.internalError('minValue must be less than or equal to maxValue');
4019
4056
  }
4020
- if (minValue < 0n || maxValue < 0n) {
4057
+ if (min < 0n || max < 0n) {
4021
4058
  internal.errors.internalError('minValue and maxValue must be greater than or equal to 0');
4022
4059
  }
4023
- return Uint64(getRandomBigInt(minValue, maxValue));
4060
+ return Uint64(getRandomBigInt(min, max));
4024
4061
  }
4025
4062
  bytes(length = MAX_BYTES_SIZE) {
4026
4063
  return Bytes(new Uint8Array(randomBytes(length)));
4027
4064
  }
4065
+ string(length = 11) {
4066
+ const setLength = 11;
4067
+ return Array(Math.ceil(length / setLength))
4068
+ .fill(0)
4069
+ .map(() => Math.random().toString(36).substring(2))
4070
+ .join('')
4071
+ .substring(0, length);
4072
+ }
4028
4073
  account(input) {
4029
4074
  const account = input?.address ?? Account(getRandomBytes(32).asAlgoTs());
4030
4075
  if (input?.address && lazyContext.ledger.accountDataMap.has(account)) {
@@ -4369,5 +4414,5 @@ class TestExecutionContext {
4369
4414
  }
4370
4415
  }
4371
4416
 
4372
- export { TestExecutionContext };
4417
+ export { TestExecutionContext, asUint8Array as bytesToUint8Array };
4373
4418
  //# sourceMappingURL=index.mjs.map