algosdk 3.4.0 → 3.5.1

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 (47) hide show
  1. package/README.md +4 -4
  2. package/dist/browser/algosdk.min.js +1 -1
  3. package/dist/browser/algosdk.min.js.map +1 -1
  4. package/dist/cjs/appAccess.js +261 -0
  5. package/dist/cjs/appAccess.js.map +1 -0
  6. package/dist/cjs/client/v2/indexer/models/types.js +266 -8
  7. package/dist/cjs/client/v2/indexer/models/types.js.map +1 -1
  8. package/dist/cjs/composer.js +13 -5
  9. package/dist/cjs/composer.js.map +1 -1
  10. package/dist/cjs/logicsig.js +54 -17
  11. package/dist/cjs/logicsig.js.map +1 -1
  12. package/dist/cjs/makeTxn.js +60 -12
  13. package/dist/cjs/makeTxn.js.map +1 -1
  14. package/dist/cjs/signing.js +4 -4
  15. package/dist/cjs/signing.js.map +1 -1
  16. package/dist/cjs/transaction.js +110 -0
  17. package/dist/cjs/transaction.js.map +1 -1
  18. package/dist/esm/appAccess.js +255 -0
  19. package/dist/esm/appAccess.js.map +1 -0
  20. package/dist/esm/client/v2/indexer/models/types.js +261 -6
  21. package/dist/esm/client/v2/indexer/models/types.js.map +1 -1
  22. package/dist/esm/composer.js +13 -5
  23. package/dist/esm/composer.js.map +1 -1
  24. package/dist/esm/logicsig.js +54 -17
  25. package/dist/esm/logicsig.js.map +1 -1
  26. package/dist/esm/makeTxn.js +60 -12
  27. package/dist/esm/makeTxn.js.map +1 -1
  28. package/dist/esm/signing.js +4 -4
  29. package/dist/esm/signing.js.map +1 -1
  30. package/dist/esm/transaction.js +110 -0
  31. package/dist/esm/transaction.js.map +1 -1
  32. package/dist/types/appAccess.d.ts +28 -0
  33. package/dist/types/client/v2/indexer/models/types.d.ts +157 -8
  34. package/dist/types/composer.d.ts +6 -2
  35. package/dist/types/logicsig.d.ts +2 -0
  36. package/dist/types/makeTxn.d.ts +9 -9
  37. package/dist/types/transaction.d.ts +18 -0
  38. package/dist/types/types/transactions/base.d.ts +76 -0
  39. package/package.json +1 -1
  40. package/src/appAccess.ts +298 -0
  41. package/src/client/v2/indexer/models/types.ts +423 -5
  42. package/src/composer.ts +24 -4
  43. package/src/logicsig.ts +68 -17
  44. package/src/makeTxn.ts +105 -12
  45. package/src/signing.ts +4 -4
  46. package/src/transaction.ts +168 -0
  47. package/src/types/transactions/base.ts +91 -0
@@ -3,7 +3,7 @@ import { AlgodClient } from './client/v2/algod/algod.js';
3
3
  import { SimulateRequest, PendingTransactionResponse, SimulateResponse } from './client/v2/algod/models/types.js';
4
4
  import { Address } from './encoding/address.js';
5
5
  import { TransactionSigner, TransactionWithSigner } from './signer.js';
6
- import { BoxReference, OnApplicationComplete, SuggestedParams } from './types/transactions/base.js';
6
+ import { BoxReference, OnApplicationComplete, ResourceReference, SuggestedParams } from './types/transactions/base.js';
7
7
  export type ABIArgument = ABIValue | TransactionWithSigner;
8
8
  /** Represents the output from a successful ABI method call. */
9
9
  export interface ABIResult {
@@ -76,7 +76,7 @@ export declare class AtomicTransactionComposer {
76
76
  * causes the current group to exceed MAX_GROUP_SIZE, or if the provided arguments are invalid
77
77
  * for the given method.
78
78
  */
79
- addMethodCall({ appID, method, methodArgs, sender, suggestedParams, onComplete, approvalProgram, clearProgram, numGlobalInts, numGlobalByteSlices, numLocalInts, numLocalByteSlices, extraPages, appAccounts, appForeignApps, appForeignAssets, boxes, note, lease, rekeyTo, signer, }: {
79
+ addMethodCall({ appID, method, methodArgs, sender, suggestedParams, onComplete, approvalProgram, clearProgram, numGlobalInts, numGlobalByteSlices, numLocalInts, numLocalByteSlices, extraPages, appAccounts, appForeignApps, appForeignAssets, boxes, access, note, lease, rekeyTo, rejectVersion, signer, }: {
80
80
  /** The ID of the smart contract to call. Set this to 0 to indicate an application creation call. */
81
81
  appID: number | bigint;
82
82
  /** The method to call on the smart contract */
@@ -111,12 +111,16 @@ export declare class AtomicTransactionComposer {
111
111
  appForeignAssets?: Array<number | bigint>;
112
112
  /** The box references for this application call */
113
113
  boxes?: BoxReference[];
114
+ /** The resource references for this application call */
115
+ access?: ResourceReference[];
114
116
  /** The note value for this application call */
115
117
  note?: Uint8Array;
116
118
  /** The lease value for this application call */
117
119
  lease?: Uint8Array;
118
120
  /** If provided, the address that the sender will be rekeyed to at the conclusion of this application call */
119
121
  rekeyTo?: string | Address;
122
+ /** The lowest application version for which this transaction should immediately fail. 0 indicates that no version check should be performed. */
123
+ rejectVersion?: number | bigint;
120
124
  /** A transaction signer that can authorize this application call from sender */
121
125
  signer: TransactionSigner;
122
126
  }): void;
@@ -20,6 +20,7 @@ export declare class LogicSig implements encoding.Encodable {
20
20
  args: Uint8Array[];
21
21
  sig?: Uint8Array;
22
22
  msig?: EncodedMultisig;
23
+ lmsig?: EncodedMultisig;
23
24
  constructor(program: Uint8Array, programArgs?: Array<Uint8Array> | null);
24
25
  getEncodingSchema(): encoding.Schema;
25
26
  toEncodingData(): Map<string, unknown>;
@@ -46,6 +47,7 @@ export declare class LogicSig implements encoding.Encodable {
46
47
  */
47
48
  appendToMultisig(secretKey: Uint8Array): void;
48
49
  signProgram(secretKey: Uint8Array): Uint8Array;
50
+ signProgramMultisig(secretKey: Uint8Array, msig: EncodedMultisig): Uint8Array;
49
51
  singleSignMultisig(secretKey: Uint8Array, msig: EncodedMultisig): [sig: Uint8Array, index: number];
50
52
  toByte(): Uint8Array;
51
53
  static fromByte(encoded: ArrayLike<any>): LogicSig;
@@ -1,5 +1,5 @@
1
1
  import { Transaction } from './transaction.js';
2
- import { SuggestedParams, PaymentTransactionParams, KeyRegistrationTransactionParams, AssetConfigurationTransactionParams, AssetTransferTransactionParams, AssetFreezeTransactionParams, ApplicationCallTransactionParams } from './types/transactions/base.js';
2
+ import { SuggestedParams, PaymentTransactionParams, KeyRegistrationTransactionParams, AssetConfigurationTransactionParams, AssetTransferTransactionParams, AssetFreezeTransactionParams, ApplicationCallTransactionParams, ApplicationCallReferenceParams } from './types/transactions/base.js';
3
3
  import { Address } from './encoding/address.js';
4
4
  /** Contains parameters common to every transaction type */
5
5
  export interface CommonTransactionParams {
@@ -120,46 +120,46 @@ export declare function makeAssetTransferTxnWithSuggestedParamsFromObject({ send
120
120
  *
121
121
  * @param options - Application call transaction parameters
122
122
  */
123
- export declare function makeApplicationCallTxnFromObject({ sender, appIndex, onComplete, appArgs, accounts, foreignApps, foreignAssets, boxes, approvalProgram, clearProgram, numLocalInts, numLocalByteSlices, numGlobalInts, numGlobalByteSlices, extraPages, note, lease, rekeyTo, suggestedParams, }: ApplicationCallTransactionParams & CommonTransactionParams): Transaction;
123
+ export declare function makeApplicationCallTxnFromObject({ sender, appIndex, onComplete, appArgs, accounts, foreignApps, foreignAssets, boxes, convertToAccess, holdings, locals, access, approvalProgram, clearProgram, numLocalInts, numLocalByteSlices, numGlobalInts, numGlobalByteSlices, extraPages, rejectVersion, note, lease, rekeyTo, suggestedParams, }: ApplicationCallTransactionParams & CommonTransactionParams & ApplicationCallReferenceParams): Transaction;
124
124
  /**
125
125
  * Make a transaction that will create an application.
126
126
  *
127
127
  * @param options - Application creation transaction parameters
128
128
  */
129
- export declare function makeApplicationCreateTxnFromObject({ sender, onComplete, appArgs, accounts, foreignApps, foreignAssets, boxes, approvalProgram, clearProgram, numLocalInts, numLocalByteSlices, numGlobalInts, numGlobalByteSlices, extraPages, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'appIndex' | 'approvalProgram' | 'clearProgram'> & Required<Pick<ApplicationCallTransactionParams, 'approvalProgram' | 'clearProgram'>> & CommonTransactionParams): Transaction;
129
+ export declare function makeApplicationCreateTxnFromObject({ sender, onComplete, appArgs, accounts, foreignApps, foreignAssets, boxes, convertToAccess, holdings, locals, access, approvalProgram, clearProgram, numLocalInts, numLocalByteSlices, numGlobalInts, numGlobalByteSlices, extraPages, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'appIndex' | 'approvalProgram' | 'clearProgram'> & Required<Pick<ApplicationCallTransactionParams, 'approvalProgram' | 'clearProgram'>> & CommonTransactionParams & ApplicationCallReferenceParams): Transaction;
130
130
  /**
131
131
  * Make a transaction that changes an application's approval and clear programs
132
132
  *
133
133
  * @param options - Application update transaction parameters
134
134
  */
135
- export declare function makeApplicationUpdateTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, approvalProgram, clearProgram, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & Required<Pick<ApplicationCallTransactionParams, 'approvalProgram' | 'clearProgram'>> & CommonTransactionParams): Transaction;
135
+ export declare function makeApplicationUpdateTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, convertToAccess, holdings, locals, access, approvalProgram, clearProgram, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & Required<Pick<ApplicationCallTransactionParams, 'approvalProgram' | 'clearProgram'>> & CommonTransactionParams & ApplicationCallReferenceParams): Transaction;
136
136
  /**
137
137
  * Make a transaction that deletes an application
138
138
  *
139
139
  * @param options - Application deletion transaction parameters
140
140
  */
141
- export declare function makeApplicationDeleteTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & CommonTransactionParams): Transaction;
141
+ export declare function makeApplicationDeleteTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, convertToAccess, holdings, locals, access, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & CommonTransactionParams & ApplicationCallReferenceParams): Transaction;
142
142
  /**
143
143
  * Make a transaction that opts in to use an application
144
144
  *
145
145
  * @param options - Application opt-in transaction parameters
146
146
  */
147
- export declare function makeApplicationOptInTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & CommonTransactionParams): Transaction;
147
+ export declare function makeApplicationOptInTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, convertToAccess, holdings, locals, access, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & CommonTransactionParams & ApplicationCallReferenceParams): Transaction;
148
148
  /**
149
149
  * Make a transaction that closes out a user's state in an application
150
150
  *
151
151
  * @param options - Application close-out transaction parameters
152
152
  */
153
- export declare function makeApplicationCloseOutTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & CommonTransactionParams): Transaction;
153
+ export declare function makeApplicationCloseOutTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, convertToAccess, holdings, locals, access, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & CommonTransactionParams & ApplicationCallReferenceParams): Transaction;
154
154
  /**
155
155
  * Make a transaction that clears a user's state in an application
156
156
  *
157
157
  * @param options - Application clear state transaction parameters
158
158
  */
159
- export declare function makeApplicationClearStateTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & CommonTransactionParams): Transaction;
159
+ export declare function makeApplicationClearStateTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, convertToAccess, holdings, locals, access, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & CommonTransactionParams & ApplicationCallReferenceParams): Transaction;
160
160
  /**
161
161
  * Make a transaction that just calls an application, doing nothing on completion
162
162
  *
163
163
  * @param options - Application no-op transaction parameters
164
164
  */
165
- export declare function makeApplicationNoOpTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & CommonTransactionParams): Transaction;
165
+ export declare function makeApplicationNoOpTxnFromObject({ sender, appIndex, appArgs, accounts, foreignApps, foreignAssets, boxes, convertToAccess, holdings, locals, access, note, lease, rekeyTo, suggestedParams, }: Omit<ApplicationCallTransactionParams, 'onComplete' | 'numLocalInts' | 'numLocalByteSlices' | 'numGlobalInts' | 'numGlobalByteSlices' | 'extraPages' | 'approvalProgram' | 'clearProgram'> & CommonTransactionParams & ApplicationCallReferenceParams): Transaction;
@@ -8,6 +8,22 @@ export interface TransactionBoxReference {
8
8
  readonly appIndex: bigint;
9
9
  readonly name: Uint8Array;
10
10
  }
11
+ export interface TransactionHoldingReference {
12
+ readonly assetIndex: bigint;
13
+ readonly address: Address;
14
+ }
15
+ export interface TransactionLocalsReference {
16
+ readonly appIndex: bigint;
17
+ readonly address: Address;
18
+ }
19
+ export interface TransactionResourceReference {
20
+ readonly address?: Readonly<Address>;
21
+ readonly appIndex?: Readonly<bigint>;
22
+ readonly assetIndex?: Readonly<bigint>;
23
+ readonly holding?: Readonly<TransactionHoldingReference>;
24
+ readonly locals?: Readonly<TransactionLocalsReference>;
25
+ readonly box?: Readonly<TransactionBoxReference>;
26
+ }
11
27
  export interface PaymentTransactionFields {
12
28
  readonly receiver: Address;
13
29
  readonly amount: bigint;
@@ -63,6 +79,8 @@ export interface ApplicationTransactionFields {
63
79
  readonly foreignApps: ReadonlyArray<bigint>;
64
80
  readonly foreignAssets: ReadonlyArray<bigint>;
65
81
  readonly boxes: ReadonlyArray<TransactionBoxReference>;
82
+ readonly access: ReadonlyArray<TransactionResourceReference>;
83
+ readonly rejectVersion: number;
66
84
  }
67
85
  export interface StateProofTransactionFields {
68
86
  readonly stateProofType: number;
@@ -134,6 +134,73 @@ export interface BoxReference {
134
134
  */
135
135
  name: Uint8Array;
136
136
  }
137
+ /**
138
+ * A grouping of the asset index and address of the account
139
+ */
140
+ export interface HoldingReference {
141
+ /**
142
+ * The asset index of the holding
143
+ */
144
+ assetIndex: number | bigint;
145
+ /**
146
+ * The address of the account holding the asset
147
+ */
148
+ address: string | Address;
149
+ }
150
+ /** A grouping of the application index and address of the account
151
+ */
152
+ export interface LocalsReference {
153
+ /**
154
+ * The application index of the local state
155
+ */
156
+ appIndex: number | bigint;
157
+ /**
158
+ * The address of the account holding the local state
159
+ */
160
+ address: string | Address;
161
+ }
162
+ /**
163
+ * Parameters for resource references in application transactions
164
+ */
165
+ export interface ApplicationCallReferenceParams {
166
+ /**
167
+ * A grouping of the asset index and address of the account
168
+ */
169
+ holdings?: HoldingReference[];
170
+ /** A grouping of the application index and address of the account
171
+ */
172
+ locals?: LocalsReference[];
173
+ /**
174
+ * If true, use the foreign accounts, apps, assets, boxes, holdings, and locals fields to construct the access list
175
+ */
176
+ convertToAccess?: boolean;
177
+ }
178
+ export interface ResourceReference {
179
+ /**
180
+ * Address string, any additional accounts to supply to the application
181
+ */
182
+ address?: string | Address;
183
+ /**
184
+ * Asset index uniquely specifying the asset
185
+ */
186
+ assetIndex?: number | bigint;
187
+ /**
188
+ * A unique application ID
189
+ */
190
+ appIndex?: number | bigint;
191
+ /**
192
+ * Holding definition: asset ID and account address
193
+ */
194
+ holding?: HoldingReference;
195
+ /**
196
+ * Local state definition: application ID and account address
197
+ */
198
+ locals?: LocalsReference;
199
+ /**
200
+ * Box definition: application ID and a name of the box
201
+ */
202
+ box?: BoxReference;
203
+ }
137
204
  /**
138
205
  * Contains payment transaction parameters.
139
206
  *
@@ -361,6 +428,15 @@ export interface ApplicationCallTransactionParams {
361
428
  * A grouping of the app ID and name of the box in an Uint8Array
362
429
  */
363
430
  boxes?: BoxReference[];
431
+ /**
432
+ * Resources accessed by the application
433
+ */
434
+ access?: ResourceReference[];
435
+ /**
436
+ * The lowest application version for which this transaction should immediately fail.
437
+ * 0 indicates that no version check should be performed.
438
+ */
439
+ rejectVersion?: number | bigint;
364
440
  }
365
441
  /**
366
442
  * Contains state proof transaction parameters.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "algosdk",
3
- "version": "3.4.0",
3
+ "version": "3.5.1",
4
4
  "description": "The official JavaScript SDK for Algorand",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -0,0 +1,298 @@
1
+ import { Address } from './encoding/address.js';
2
+ import {
3
+ BoxReference,
4
+ HoldingReference,
5
+ LocalsReference,
6
+ ResourceReference,
7
+ } from './types/transactions/base.js';
8
+ import { ensureSafeUnsignedInteger } from './utils/utils.js';
9
+
10
+ /**
11
+ * resourceReferencesToEncodingData translates an array of ResourceReferences into an array of encoding data
12
+ * maps.
13
+ */
14
+ export function resourceReferencesToEncodingData(
15
+ appIndex: bigint,
16
+ references: ReadonlyArray<ResourceReference>
17
+ ): Array<Map<string, unknown>> {
18
+ const accessList: Array<Map<string, unknown>> = [];
19
+
20
+ function ensure(target: ResourceReference): number {
21
+ for (let idx = 0; idx < accessList.length; idx++) {
22
+ const a = accessList[idx];
23
+ if (
24
+ a.get('d') === target.address &&
25
+ a.get('s') === target.assetIndex &&
26
+ a.get('p') === target.appIndex
27
+ ) {
28
+ return idx + 1; // 1-based index
29
+ }
30
+ }
31
+ if (target.address) {
32
+ accessList.push(new Map<string, unknown>([['d', target.address]]));
33
+ }
34
+ if (target.assetIndex) {
35
+ accessList.push(new Map<string, unknown>([['s', target.assetIndex]]));
36
+ }
37
+ if (target.appIndex) {
38
+ accessList.push(new Map<string, unknown>([['p', target.appIndex]]));
39
+ }
40
+ return accessList.length; // length is 1-based position of new element
41
+ }
42
+
43
+ const zeroAddr = Address.zeroAddress();
44
+ for (const rr of references) {
45
+ if (rr.address || rr.assetIndex || rr.appIndex) {
46
+ ensure(rr);
47
+ continue;
48
+ }
49
+
50
+ if (rr.holding) {
51
+ const h = rr.holding;
52
+ let addrIdx = 0;
53
+ if (h.address && !(h.address as Address).equals(zeroAddr)) {
54
+ addrIdx = ensure({ address: h.address });
55
+ }
56
+ const assetIdx = ensure({ assetIndex: h.assetIndex });
57
+ accessList.push(
58
+ new Map<string, unknown>([
59
+ [
60
+ 'h',
61
+ new Map<string, unknown>([
62
+ ['d', addrIdx],
63
+ ['s', assetIdx],
64
+ ]),
65
+ ],
66
+ ])
67
+ );
68
+ continue;
69
+ }
70
+ if (rr.locals) {
71
+ const l = rr.locals;
72
+ let addrIdx = 0;
73
+ if (l.address && !(l.address as Address).equals(zeroAddr)) {
74
+ addrIdx = ensure({ address: l.address });
75
+ }
76
+ let appIdx = 0;
77
+ if (l.appIndex && BigInt(l.appIndex) !== appIndex) {
78
+ appIdx = ensure({ appIndex: l.appIndex });
79
+ }
80
+ accessList.push(
81
+ new Map<string, unknown>([
82
+ [
83
+ 'l',
84
+ new Map<string, unknown>([
85
+ ['d', addrIdx],
86
+ ['p', appIdx],
87
+ ]),
88
+ ],
89
+ ])
90
+ );
91
+ continue;
92
+ }
93
+ if (rr.box) {
94
+ const b = rr.box;
95
+ let appIdx = 0;
96
+ if (b.appIndex && BigInt(b.appIndex) !== appIndex) {
97
+ appIdx = ensure({ appIndex: b.appIndex });
98
+ }
99
+ accessList.push(
100
+ new Map<string, unknown>([
101
+ [
102
+ 'b',
103
+ new Map<string, unknown>([
104
+ ['i', appIdx],
105
+ ['n', b.name],
106
+ ]),
107
+ ],
108
+ ])
109
+ );
110
+ }
111
+ }
112
+ return accessList;
113
+ }
114
+
115
+ export function convertIndicesToResourceReferences(
116
+ accessList: Array<Map<string, unknown>>
117
+ ): Array<ResourceReference> {
118
+ const references: Array<ResourceReference> = [];
119
+ for (const item of accessList) {
120
+ const address = item.get('d') as Address | undefined;
121
+ const assetIndex = item.get('s') as bigint | undefined;
122
+ const appIndex = item.get('p') as bigint | undefined;
123
+ if (address) {
124
+ references.push({ address });
125
+ continue;
126
+ }
127
+ if (assetIndex) {
128
+ references.push({ assetIndex });
129
+ continue;
130
+ }
131
+ if (appIndex) {
132
+ references.push({ appIndex });
133
+ continue;
134
+ }
135
+ const holding = item.get('h') as Map<string, unknown> | undefined;
136
+ if (holding) {
137
+ const hAddressIndex = ensureSafeUnsignedInteger(holding.get('d') ?? 0);
138
+ const hAssetIndex = ensureSafeUnsignedInteger(holding.get('s'));
139
+ if (!hAssetIndex) {
140
+ throw new Error(`Holding missing asset index: ${holding}`);
141
+ }
142
+ const hAddress =
143
+ hAddressIndex === 0
144
+ ? Address.zeroAddress()
145
+ : (references[hAddressIndex - 1].address as Address);
146
+ const asset = references[hAssetIndex - 1].assetIndex as bigint;
147
+ references.push({ holding: { address: hAddress, assetIndex: asset } });
148
+ continue;
149
+ }
150
+ const locals = item.get('l') as Map<string, unknown> | undefined;
151
+ if (locals) {
152
+ const lAddressIndex = ensureSafeUnsignedInteger(locals.get('d') ?? 0);
153
+ const lAppIndex = ensureSafeUnsignedInteger(locals.get('p') ?? 0);
154
+ const lAddress =
155
+ lAddressIndex === 0
156
+ ? Address.zeroAddress()
157
+ : (references[lAddressIndex - 1].address as Address);
158
+ const app =
159
+ lAppIndex === 0
160
+ ? BigInt(0)
161
+ : (references[lAppIndex - 1].appIndex as bigint);
162
+ references.push({ locals: { address: lAddress, appIndex: app } });
163
+ continue;
164
+ }
165
+ const box = item.get('b') as Map<string, unknown> | undefined;
166
+ if (box) {
167
+ const bAppIndex = ensureSafeUnsignedInteger(box.get('i') ?? 0);
168
+ const name = box.get('n') as Uint8Array;
169
+ if (!name) {
170
+ throw new Error(`Box missing name: ${box}`);
171
+ }
172
+ const app =
173
+ bAppIndex === 0
174
+ ? BigInt(0)
175
+ : (references[bAppIndex - 1].appIndex as number | bigint);
176
+ references.push({ box: { appIndex: app, name } });
177
+ }
178
+ }
179
+ return references;
180
+ }
181
+
182
+ /**
183
+ * foreignArraysToResourceReferences makes a single array of ResourceReferences from various foreign resource arrays.
184
+ * Note, runtime representation of ResourceReference uses addresses, app and asset identifiers, not indexes.
185
+ *
186
+ * @param accounts - optional array of accounts
187
+ * @param foreignAssets - optional array of foreign assets
188
+ * @param foreignApps - optional array of foreign apps
189
+ * @param holdings - optional array of holdings
190
+ * @param locals - optional array of locals
191
+ * @param boxes - optional array of boxes
192
+ */
193
+ export function foreignArraysToResourceReferences({
194
+ appIndex,
195
+ accounts,
196
+ foreignAssets,
197
+ foreignApps,
198
+ holdings,
199
+ locals,
200
+ boxes,
201
+ }: {
202
+ appIndex: bigint | number;
203
+ accounts?: ReadonlyArray<string | Address>;
204
+ foreignAssets?: ReadonlyArray<number | bigint>;
205
+ foreignApps?: ReadonlyArray<number | bigint>;
206
+ holdings?: ReadonlyArray<HoldingReference>;
207
+ locals?: ReadonlyArray<LocalsReference>;
208
+ boxes?: ReadonlyArray<BoxReference>;
209
+ }): Array<ResourceReference> {
210
+ const accessList: Array<ResourceReference> = [];
211
+ function ensureAddress(addr: string | Address) {
212
+ let addr2: Address;
213
+ if (typeof addr === 'string') {
214
+ if (addr === '') {
215
+ return;
216
+ }
217
+ addr2 = Address.fromString(addr);
218
+ } else {
219
+ addr2 = addr;
220
+ }
221
+ if (addr2.equals(Address.zeroAddress())) {
222
+ return;
223
+ }
224
+ let addrFound = false;
225
+ for (const rr of accessList) {
226
+ if (!rr.address) {
227
+ continue;
228
+ }
229
+ let rrAddress = rr.address;
230
+ if (typeof rr.address === 'string') {
231
+ rrAddress = Address.fromString(rr.address);
232
+ }
233
+ if ((rrAddress as Address).equals(addr2)) {
234
+ addrFound = true;
235
+ break;
236
+ }
237
+ }
238
+ if (!addrFound) {
239
+ accessList.push({ address: addr });
240
+ }
241
+ }
242
+ function ensureAsset(asset: number | bigint) {
243
+ let assetFound = false;
244
+ for (const rr of accessList) {
245
+ if (rr.assetIndex === asset) {
246
+ assetFound = true;
247
+ break;
248
+ }
249
+ }
250
+ if (!assetFound) {
251
+ accessList.push({ assetIndex: asset });
252
+ }
253
+ }
254
+ function ensureApp(app: number | bigint) {
255
+ let appFound = false;
256
+ for (const rr of accessList) {
257
+ if (rr.appIndex === app) {
258
+ appFound = true;
259
+ break;
260
+ }
261
+ }
262
+ if (!appFound) {
263
+ accessList.push({ appIndex: app });
264
+ }
265
+ }
266
+ for (const acct of accounts ?? []) {
267
+ ensureAddress(acct);
268
+ }
269
+ for (const asset of foreignAssets ?? []) {
270
+ ensureAsset(asset);
271
+ }
272
+ for (const app of foreignApps ?? []) {
273
+ ensureApp(app);
274
+ }
275
+ for (const holding of holdings ?? []) {
276
+ if (holding.address) {
277
+ ensureAddress(holding.address);
278
+ }
279
+ ensureAsset(holding.assetIndex);
280
+ accessList.push({ holding });
281
+ }
282
+ for (const local of locals ?? []) {
283
+ if (local.address) {
284
+ ensureAddress(local.address);
285
+ }
286
+ if (local.appIndex && BigInt(local.appIndex) !== appIndex) {
287
+ ensureApp(local.appIndex);
288
+ }
289
+ accessList.push({ locals: local });
290
+ }
291
+ for (const box of boxes ?? []) {
292
+ if (box.appIndex && BigInt(box.appIndex) !== appIndex) {
293
+ ensureApp(box.appIndex);
294
+ }
295
+ accessList.push({ box });
296
+ }
297
+ return accessList;
298
+ }