Skip to content

Commit 8123e0e

Browse files
fix: correctly set action amount for authority actions
1 parent f140252 commit 8123e0e

File tree

3 files changed

+99
-36
lines changed

3 files changed

+99
-36
lines changed

src/nano_contracts/builder.ts

+43-32
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@ import {
1616
NATIVE_TOKEN_UID,
1717
NANO_CONTRACTS_INITIALIZE_METHOD,
1818
TOKEN_MINT_MASK,
19-
TOKEN_MELT_MASK
19+
TOKEN_MELT_MASK,
2020
} from '../constants';
2121
import Serializer from './serializer';
2222
import HathorWallet from '../new/wallet';
2323
import { NanoContractTransactionError, UtxoError } from '../errors';
2424
import {
25-
ActionTypeToActionHeaderType,
2625
NanoContractActionHeader,
2726
NanoContractActionType,
2827
NanoContractAction,
@@ -32,9 +31,9 @@ import {
3231
NanoContractBuilderCreateTokenOptions,
3332
NanoContractVertexType,
3433
} from './types';
35-
import { IDataInput, IDataOutput, ITokenData } from '../types';
34+
import { IDataInput, IDataOutput } from '../types';
3635
import ncApi from '../api/nano';
37-
import { validateAndUpdateBlueprintMethodArgs } from './utils';
36+
import { mapActionToActionHeader, validateAndUpdateBlueprintMethodArgs } from './utils';
3837
import NanoContractHeader from './header';
3938

4039
class NanoContractTransactionBuilder {
@@ -350,7 +349,9 @@ class NanoContractTransactionBuilder {
350349
}
351350

352351
if (!action.authority || !action.token) {
353-
throw new NanoContractTransactionError('Authority and token are required for grant authority action.');
352+
throw new NanoContractTransactionError(
353+
'Authority and token are required for grant authority action.'
354+
);
354355
}
355356

356357
const authorityAddressParam = action.authorityAddress;
@@ -359,10 +360,16 @@ class NanoContractTransactionBuilder {
359360
}
360361

361362
// Get the utxos with the authority of the action and create the input
362-
const utxos = await this.wallet.getAuthorityUtxo(action.token, action.authority, { many: false, only_available_utxos: true, filter_address: action.address });
363+
const utxos = await this.wallet.getAuthorityUtxo(action.token, action.authority, {
364+
many: false,
365+
only_available_utxos: true,
366+
filter_address: action.address,
367+
});
363368

364369
if (!utxos || utxos.length === 0) {
365-
throw new NanoContractTransactionError('Not enough authority utxos to execute the grant authority.');
370+
throw new NanoContractTransactionError(
371+
'Not enough authority utxos to execute the grant authority.'
372+
);
366373
}
367374

368375
const inputs: IDataInput[] = [];
@@ -533,17 +540,35 @@ class NanoContractTransactionBuilder {
533540
tokens = Array.from(tokenSet);
534541
for (const action of this.actions) {
535542
// Call action
536-
if (action.type === NanoContractActionType.DEPOSIT) {
537-
const ret = await this.executeDeposit(action, tokens);
538-
inputs = concat(inputs, ret[0]);
539-
outputs = concat(outputs, ret[1]);
540-
} else if (action.type === NanoContractActionType.WITHDRAWAL) {
541-
const output = this.executeWithdrawal(action, tokens);
542-
if (output) {
543-
outputs = concat(outputs, output);
543+
switch (action.type) {
544+
case NanoContractActionType.DEPOSIT: {
545+
const retDeposit = await this.executeDeposit(action);
546+
inputs = concat(inputs, retDeposit[0]);
547+
outputs = concat(outputs, retDeposit[1]);
548+
break;
549+
}
550+
case NanoContractActionType.WITHDRAWAL: {
551+
const outputWithdrawal = this.executeWithdrawal(action);
552+
if (outputWithdrawal) {
553+
outputs = concat(outputs, outputWithdrawal);
554+
}
555+
break;
556+
}
557+
case NanoContractActionType.GRANT_AUTHORITY: {
558+
const retGrant = await this.executeGrantAuthority(action);
559+
inputs = concat(inputs, retGrant[0]);
560+
outputs = concat(outputs, retGrant[1]);
561+
break;
562+
}
563+
case NanoContractActionType.INVOKE_AUTHORITY: {
564+
const outputInvoke = this.executeInvokeAuthority(action);
565+
if (outputInvoke) {
566+
outputs = concat(outputs, outputInvoke);
567+
}
568+
break;
544569
}
545-
} else {
546-
throw new Error('Invalid type for nano contract action.');
570+
default:
571+
throw new Error('Invalid type for nano contract action.');
547572
}
548573
}
549574
}
@@ -646,21 +671,7 @@ class NanoContractTransactionBuilder {
646671

647672
if (this.actions) {
648673
nanoHeaderActions = this.actions.map(action => {
649-
const headerActionType = ActionTypeToActionHeaderType[action.type];
650-
651-
const mappedTokens: ITokenData[] = tokens.map(token => {
652-
return {
653-
uid: token,
654-
name: '',
655-
symbol: '',
656-
};
657-
});
658-
659-
return {
660-
type: headerActionType,
661-
amount: action.amount,
662-
tokenIndex: tokensUtils.getTokenIndex(mappedTokens, action.token),
663-
};
674+
return mapActionToActionHeader(action, tokens);
664675
});
665676
}
666677

src/nano_contracts/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export enum NanoContractActionType {
2424
DEPOSIT = 'deposit',
2525
WITHDRAWAL = 'withdrawal',
2626
GRANT_AUTHORITY = 'grant_authority',
27-
INVOKE_AUTHORITY = 'invoke_authority'
27+
INVOKE_AUTHORITY = 'invoke_authority',
2828
}
2929

3030
export enum NanoContractHeaderActionType {

src/nano_contracts/utils.ts

+55-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import { get } from 'lodash';
99
import { crypto } from 'bitcore-lib';
1010
import transactionUtils from '../utils/transaction';
11+
import tokensUtils from '../utils/tokens';
1112
import SendTransaction from '../new/sendTransaction';
1213
import HathorWallet from '../new/wallet';
1314
import Network from '../models/network';
@@ -20,10 +21,17 @@ import Address from '../models/address';
2021
import Transaction from '../models/transaction';
2122
import { NanoContractTransactionError, OracleParseError, WalletFromXPubGuard } from '../errors';
2223
import { OutputType } from '../wallet/types';
23-
import { IHistoryTx, IStorage } from '../types';
24+
import { IHistoryTx, IStorage, ITokenData } from '../types';
2425
import { parseScript } from '../utils/scripts';
25-
import { MethodArgInfo, NanoContractArgumentType } from './types';
26-
import { NANO_CONTRACTS_INITIALIZE_METHOD } from '../constants';
26+
import {
27+
ActionTypeToActionHeaderType,
28+
MethodArgInfo,
29+
NanoContractArgumentType,
30+
NanoContractAction,
31+
NanoContractActionHeader,
32+
NanoContractActionType,
33+
} from './types';
34+
import { NANO_CONTRACTS_INITIALIZE_METHOD, TOKEN_MELT_MASK, TOKEN_MINT_MASK } from '../constants';
2735

2836
/**
2937
* Sign a transaction and create a send transaction object
@@ -258,3 +266,47 @@ export const validateAndUpdateBlueprintMethodArgs = async (
258266
export const isNanoContractCreateTx = (tx: IHistoryTx): boolean => {
259267
return tx.nc_method === NANO_CONTRACTS_INITIALIZE_METHOD;
260268
};
269+
270+
/**
271+
* Map a NanoContractAction object to NanoContractActionHeader
272+
*
273+
* @param action The action object to be mapped
274+
* @param tokens The tokens array to be used in the mapping
275+
*
276+
* @return The mapped action header object
277+
*/
278+
export const mapActionToActionHeader = (
279+
action: NanoContractAction,
280+
tokens: string[]
281+
): NanoContractActionHeader => {
282+
const headerActionType = ActionTypeToActionHeaderType[action.type];
283+
284+
const mappedTokens: ITokenData[] = tokens.map(token => {
285+
return {
286+
uid: token,
287+
name: '',
288+
symbol: '',
289+
};
290+
});
291+
292+
let amount;
293+
if (
294+
action.type === NanoContractActionType.GRANT_AUTHORITY ||
295+
action.type === NanoContractActionType.INVOKE_AUTHORITY
296+
) {
297+
amount = action.authority === 'mint' ? TOKEN_MINT_MASK : TOKEN_MELT_MASK;
298+
} else if (
299+
action.type === NanoContractActionType.DEPOSIT ||
300+
action.type === NanoContractActionType.WITHDRAWAL
301+
) {
302+
amount = action.amount;
303+
} else {
304+
throw new Error('Invalid nano contract action type');
305+
}
306+
307+
return {
308+
type: headerActionType,
309+
amount,
310+
tokenIndex: tokensUtils.getTokenIndex(mappedTokens, action.token),
311+
};
312+
};

0 commit comments

Comments
 (0)