Skip to content

Commit

Permalink
Enhancement: Add foreign array objects to ATC addMethodCall (#725)
Browse files Browse the repository at this point in the history
* Add foreign array objects to ATC addmethodcall

* Copy array value so that inputs are not modified
  • Loading branch information
algochoi authored Jan 10, 2023
1 parent 3b54c12 commit e411146
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/composer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ export class AtomicTransactionComposer {
numLocalInts,
numLocalByteSlices,
extraPages,
appAccounts,
appForeignApps,
appForeignAssets,
boxes,
note,
lease,
Expand Down Expand Up @@ -234,6 +237,12 @@ export class AtomicTransactionComposer {
numLocalByteSlices?: number;
/** The number of extra pages to allocate for the application's programs. Only set this if this is an application creation call. If omitted, defaults to 0. */
extraPages?: number;
/** Array of Address strings that represent external accounts supplied to this application. If accounts are provided here, the accounts specified in the method args will appear after these. */
appAccounts?: string[];
/** Array of App ID numbers that represent external apps supplied to this application. If apps are provided here, the apps specified in the method args will appear after these. */
appForeignApps?: number[];
/** Array of Asset ID numbers that represent external assets supplied to this application. If assets are provided here, the assets specified in the method args will appear after these. */
appForeignAssets?: number[];
/** The box references for this application call */
boxes?: BoxReference[];
/** The note value for this application call */
Expand Down Expand Up @@ -370,9 +379,12 @@ export class AtomicTransactionComposer {
}

const resolvedRefIndexes: number[] = [];
const foreignAccounts: string[] = [];
const foreignApps: number[] = [];
const foreignAssets: number[] = [];
const foreignAccounts: string[] =
appAccounts == null ? [] : appAccounts.slice();
const foreignApps: number[] =
appForeignApps == null ? [] : appForeignApps.slice();
const foreignAssets: number[] =
appForeignAssets == null ? [] : appForeignAssets.slice();
for (let i = 0; i < refArgTypes.length; i++) {
const refType = refArgTypes[i];
const refValue = refArgValues[i];
Expand Down
59 changes: 59 additions & 0 deletions tests/10.ABI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ import {
ABIType,
ABIValue,
} from '../src/abi/abi_type';
import {
AtomicTransactionComposer,
ABIMethod,
makeBasicAccountTransactionSigner,
generateAccount,
AtomicTransactionComposerStatus,
} from '../src';
import { decodeAddress } from '../src/encoding/address';

describe('ABI type checking', () => {
Expand Down Expand Up @@ -474,4 +481,56 @@ describe('ABI encoding', () => {
])
);
});

it('should properly accept foreign array objects in the ATC addMethodCall', () => {
const composer = new AtomicTransactionComposer();
const method = ABIMethod.fromSignature('add(application)uint8');
const account = generateAccount();
const sender = 'DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA';
const sp = {
fee: 1000,
firstRound: 1,
lastRound: 1001,
genesisID: 'gi',
genesisHash: 'gh',
};
const foreignAcct =
'E4VCHISDQPLIZWMALIGNPK2B2TERPDMR64MZJXE3UL75MUDXZMADX5OWXM';

// Create method call using ATC.
// The foreign apps array argument should be packed before the method argument.
composer.addMethodCall({
appID: 7,
method,
sender,
suggestedParams: sp,
methodArgs: [2],
appAccounts: [foreignAcct],
appForeignApps: [1],
appForeignAssets: [124],
signer: makeBasicAccountTransactionSigner(account),
});

assert.deepStrictEqual(
composer.getStatus(),
AtomicTransactionComposerStatus.BUILDING
);
assert.deepStrictEqual(composer.count(), 1);

// The built group should have one txn.
const txns = composer.buildGroup();
// eslint-disable-next-line prefer-destructuring
const txn = txns[0].txn;

// Assert that foreign objects were passed in and ordering was correct.
assert.deepStrictEqual(txn.appForeignApps?.length, 2);
assert.deepStrictEqual(txn.appForeignApps[0], 1);
assert.deepStrictEqual(txn.appForeignApps[1], 2);

assert.deepStrictEqual(txn.appForeignAssets?.length, 1);
assert.deepStrictEqual(txn.appForeignAssets[0], 124);

assert.deepStrictEqual(txn.appAccounts?.length, 1);
assert.deepStrictEqual(txn.appAccounts[0], decodeAddress(foreignAcct));
});
});

0 comments on commit e411146

Please sign in to comment.