Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't serialize args in account.ts #354

Merged
merged 5 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/account.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions lib/account.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion lib/transaction.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion lib/transaction.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 10 additions & 5 deletions src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,16 +268,16 @@ export class Account {
/**
* @param contractId NEAR account where the contract is deployed
* @param methodName The method name on the contract as it is written in the contract code
* @param args Any arguments to the contract method, wrapped in JSON
* @param data The compiled contract code
* @param gas An amount of yoctoⓃ attached to cover the gas cost of this function call
* @param amount Payment in yoctoⓃ that is sent to the contract during this function call
* @param args arguments to pass to method. Can be either plain JS object which gets serialized as JSON automatically
* or `Uint8Array` instance which represents bytes passed as is.
* @param gas max amount of gas that method call can use
* @param deposit amount of NEAR (in yoctoNEAR) to send together with the call
* @returns {Promise<FinalExecutionOutcome>}
*/
async functionCall(contractId: string, methodName: string, args: any, gas?: BN, amount?: BN): Promise<FinalExecutionOutcome> {
args = args || {};
this.validateArgs(args);
return this.signAndSendTransaction(contractId, [functionCall(methodName, Buffer.from(JSON.stringify(args)), gas || DEFAULT_FUNC_CALL_GAS, amount)]);
return this.signAndSendTransaction(contractId, [functionCall(methodName, args, gas || DEFAULT_FUNC_CALL_GAS, amount)]);
}

/**
Expand Down Expand Up @@ -316,6 +316,11 @@ export class Account {
}

private validateArgs(args: any) {
const isUint8Array = args.byteLength !== undefined && args.byteLength === args.length;
if (isUint8Array) {
return;
}

if (Array.isArray(args) || typeof args !== 'object') {
throw new PositionalArgsError();
}
Expand Down
16 changes: 14 additions & 2 deletions src/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,20 @@ export function deployContract(code: Uint8Array): Action {
return new Action({ deployContract: new DeployContract({code}) });
}

export function functionCall(methodName: string, args: Uint8Array, gas: BN, deposit: BN): Action {
return new Action({functionCall: new FunctionCall({methodName, args, gas, deposit }) });
/**
* Constructs {@link Action} instance representing contract method call.
*
* @param methodName the name of the method to call
* @param args arguments to pass to method. Can be either plain JS object which gets serialized as JSON automatically
* or `Uint8Array` instance which represents bytes passed as is.
* @param gas max amount of gas that method call can use
* @param deposit amount of NEAR (in yoctoNEAR) to send together with the call
*/
export function functionCall(methodName: string, args: Uint8Array | object, gas: BN, deposit: BN): Action {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind adding comments to the function? Specifically a note about the possible formats for args would be very helpful. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

const anyArgs = args as any;
const isUint8Array = anyArgs.byteLength !== undefined && anyArgs.byteLength === anyArgs.length;
const serializedArgs = isUint8Array ? args : Buffer.from(JSON.stringify(args));
return new Action({functionCall: new FunctionCall({methodName, args: serializedArgs, gas, deposit }) });
}

export function transfer(deposit: BN): Action {
Expand Down
28 changes: 28 additions & 0 deletions test/transaction.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const { functionCall } = require('../lib/transaction');
const BN = require('bn.js');

test('functionCall with already serialized args', () => {
const serializedArgs = Buffer.from('{}');
const action = functionCall('methodName', serializedArgs, new BN(1), new BN(2));
expect(action).toMatchObject({
functionCall: {
methodName: 'methodName',
args: serializedArgs,
gas: new BN(1),
deposit: new BN(2)
}
});
});

test('functionCall with non-serialized args', () => {
const serializedArgs = Buffer.from('{}');
const action = functionCall('methodName', {}, new BN(1), new BN(2));
expect(action).toMatchObject({
functionCall: {
methodName: 'methodName',
args: serializedArgs,
gas: new BN(1),
deposit: new BN(2)
}
});
});