Skip to content

Commit

Permalink
feat: added token transfer for callMethod (#85)
Browse files Browse the repository at this point in the history
* feat: added token transfer for callMethod

* chore: methodHash is methodId now

* chore: renaming
  • Loading branch information
ohager authored Dec 30, 2024
1 parent 7b0e33b commit dac837f
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 21 deletions.
6 changes: 3 additions & 3 deletions packages/contracts/src/__tests__/generateMethodCall.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import {generateMethodCall} from '../generateMethodCall';

const ContractMethodHash = '-327803124352370';
const ContractMethodId = '-327803124352370';

describe('generateMethodCall', () => {
it('generates a method call without argument', () => {
const message = generateMethodCall({
methodHash: ContractMethodHash
methodId: ContractMethodId
});
expect(message).toBe('8e7a3763ddd5feff');
});

it('generates a method call with three arguments', () => {
const message = generateMethodCall({
methodHash: ContractMethodHash,
methodId: ContractMethodId,
methodArgs: [true, 1234, '-1234567890'],
});
expect(message).toBe('8e7a3763ddd5feff0100000000000000d2040000000000002efd69b6ffffffff');
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/src/generateMethodCall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {convertContractData} from './internal/convertContractData';
* @return A hex string that can be used as contracts transaction message
*/
export const generateMethodCall = (args: GenerateMethodCallArgs): string => {
const argArray = args.methodArgs ? [args.methodHash, ...args.methodArgs] : [args.methodHash];
const argArray = args.methodArgs ? [args.methodId, ...args.methodArgs] : [args.methodId];
return argArray
.map(convertContractData)
.map(long => convertDecStringToHexString(long, 16))
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts/src/typings/args/generateMethodCallArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import {ContractData} from '../contractData';
/**
* The argument object for {@link generateMethodCall}
*
* @param {string} methodHash The signed long hash for the method generated by BlockTalk compiler
* @param {string} methodId The signed long hash for the method generated by BlockTalk compiler
* @param {ContractData[]} methodArgs Optional argument list for the method.
* The arguments must be numerical, and cannot be alphanumeric. To convert a short text (max 8 chars/bytes) into a numerical representation
* use {@link convertShortStringToContractData}
*
*/
export interface GenerateMethodCallArgs {
methodHash: string;
methodId: string;
methodArgs?: ContractData[];
}
54 changes: 52 additions & 2 deletions packages/core/src/api/__tests__/contractApi.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
getContract,
getContractsByAccount,
publishContract,
getSingleContractMapValue, getContractMapValuesByFirstKey, getAllContractsByCodeHash
getSingleContractMapValue, getContractMapValuesByFirstKey, getAllContractsByCodeHash, callContractMethod
} from '../factories/contract';
import {TransactionId} from '../../typings/transactionId';

Expand Down Expand Up @@ -146,7 +146,6 @@ describe('Contract Api', () => {
vi.resetAllMocks();
});


it('should publish contract', async () => {

// @ts-ignore
Expand Down Expand Up @@ -232,4 +231,55 @@ describe('Contract Api', () => {
expect(contractList.ats).toHaveLength(0);
});
});

describe('callContractMethod', () => {

const mockResponse = {
transaction: 'transaction',
requestProcessingTime: 1
};

it('should getAllContracts using signa only', async () => {

httpMock = HttpMockBuilder.create()
.onPostReply(200, mockResponse,
'relPath?requestType=sendMoney&message=640000000000000001000000000000000200000000000000&messageIsText=false&amountNQT=2000&publicKey=senderPublicKey&recipient=contractId&feeNQT=feePlanck&deadline=1440'
)
.build();
const service = createChainService(httpMock, 'relPath');
const contractList = await callContractMethod(service)({
contractId: 'contractId',
feePlanck: 'feePlanck',
methodId: '100',
methodArgs: ['1','2'],
senderPrivateKey: 'senderPrivateKey',
senderPublicKey: 'senderPublicKey',
amountPlanck: '2000',
skipAdditionalSecurityCheck: true
}) as TransactionId;
expect(contractList.transaction).toMatch('transaction');
});

it('should getAllContracts using tokens', async () => {
httpMock = HttpMockBuilder.create()
.onPostReply(200, mockResponse,
'relPath?requestType=transferAsset&message=640000000000000001000000000000000200000000000000&messageIsText=false&asset=assetId&quantityQNT=1000000&publicKey=senderPublicKey&recipient=contractId&feeNQT=feePlanck&amountNQT=assetId&deadline=1440',
)
.build();
const service = createChainService(httpMock, 'relPath');
const contractList = await callContractMethod(service)({
contractId: 'contractId',
feePlanck: 'feePlanck',
methodId: '100',
methodArgs: ['1','2'],
senderPrivateKey: 'senderPrivateKey',
senderPublicKey: 'senderPublicKey',
amountPlanck: '2000',
assetId: 'assetId',
assetQuantity: '1000000',
skipAdditionalSecurityCheck: true
}) as TransactionId;
expect(contractList.transaction).toMatch('transaction');
});
});
});
3 changes: 2 additions & 1 deletion packages/core/src/api/factories/asset/transferAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export const transferAsset = (service: ChainService) =>
feeNQT: a.feePlanck,
amountNQT: a.amountPlanck || undefined,
deadline: a.deadline || DefaultDeadline,
referencedTransactionFullHash: a.referencedTransactionFullHash
referencedTransactionFullHash: a.referencedTransactionFullHash,
skipAdditionalSecurityCheck: a.skipAdditionalSecurityCheck
};

if (a.attachment) {
Expand Down
36 changes: 26 additions & 10 deletions packages/core/src/api/factories/contract/callContractMethod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,27 @@
* Modified (c) 2022 Signum Network
*/
import {ChainService} from '../../../service';
import {CallContractMethodArgs, SendAmountArgs} from '../../../typings/args';
import {CallContractMethodArgs} from '../../../typings/args';
import {TransactionId} from '../../../typings/transactionId';
import {AttachmentMessage} from '../../../typings/attachment';
import {sendAmountToSingleRecipient} from '../transaction';
import {generateMethodCall} from '@signumjs/contracts';
import {UnsignedTransaction} from '../../../typings/unsignedTransaction';
import {transferAsset} from '../asset';


/**
* Use with {@link ApiComposer} and belongs to {@link ContractApi}.
*
* See details at {@link ContractApi.callContractMethod}
*
* @category factories
*/
*
* @category factories
*/
export const callContractMethod = (service: ChainService) =>
async (args: CallContractMethodArgs): Promise<TransactionId | UnsignedTransaction> => {

const callMessage = generateMethodCall({
methodHash: args.methodHash,
methodId: args.methodId,
methodArgs: args.methodArgs,
});

Expand All @@ -31,17 +32,32 @@ export const callContractMethod = (service: ChainService) =>
messageIsText: false,
});

const parameters: SendAmountArgs = {
if (args.assetId && args.assetQuantity) {
return transferAsset(service)({
amountPlanck: args.assetId,
assetId: args.assetId,
quantity: args.assetQuantity,
attachment,
deadline: args.deadline,
senderPublicKey: args.senderPublicKey,
referencedTransactionFullHash: args.referencedTransactionFullHash,
feePlanck: args.feePlanck,
recipientId: args.contractId,
senderPrivateKey: args.senderPrivateKey,
skipAdditionalSecurityCheck: args.skipAdditionalSecurityCheck
});
}

return sendAmountToSingleRecipient(service)({
amountPlanck: args.amountPlanck,
attachment,
deadline: args.deadline,
feePlanck: args.feePlanck,
recipientId: args.contractId,
senderPrivateKey: args.senderPrivateKey,
senderPublicKey: args.senderPublicKey,
referencedTransactionFullHash: args.referencedTransactionFullHash
};

return sendAmountToSingleRecipient(service)(parameters);
referencedTransactionFullHash: args.referencedTransactionFullHash,
skipAdditionalSecurityCheck: args.skipAdditionalSecurityCheck
});

};
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ export const sendAmountToSingleRecipient = (service: ChainService) =>
recipientPublicKey,
feeNQT: a.feePlanck,
deadline: a.deadline || DefaultDeadline,
referencedTransactionFullHash: a.referencedTransactionFullHash
referencedTransactionFullHash: a.referencedTransactionFullHash,
skipAdditionalSecurityCheck: a.skipAdditionalSecurityCheck
};

if (a.attachment) {
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/typings/args/callContractMethodArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import {DefaultSendArgs} from './defaultSendArgs';
*/
export interface CallContractMethodArgs extends DefaultSendArgs {
amountPlanck: string;
assetId?: string;
assetQuantity?: string;
contractId: string;
methodArgs?: ContractData[];
methodHash: string;
methodId: string;
}

0 comments on commit dac837f

Please sign in to comment.