Skip to content

Commit 0a1d3f3

Browse files
committed
handle sft giveaway endpoint
1 parent 9fbd512 commit 0a1d3f3

File tree

7 files changed

+295
-193
lines changed

7 files changed

+295
-193
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
### [1.29.0](https://github.com/ElvenTools/elven-tools-cli/releases/tag/v1.29.0) (2024-02-10)
2+
- handle a giveaway endpoint for SFT minter SC
3+
- update dependencies
4+
15
### [1.28.0](https://github.com/ElvenTools/elven-tools-cli/releases/tag/v1.28.0) (2024-01-06)
2-
- add possibility to define special roles for nft minter
3-
- update dependencies
6+
- add possibility to define special roles for nft minter
7+
- update dependencies
48

59
### [1.27.0](https://github.com/ElvenTools/elven-tools-cli/releases/tag/v1.27.0) (2024-01-05)
610
- add possibility to define special roles for sft minter

package-lock.json

Lines changed: 175 additions & 175 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
"engines": {
44
"node": ">=18.0.0"
55
},
6-
"version": "1.28.0",
6+
"version": "1.29.0",
77
"elvenTools": {
88
"nftSmartContractVersionTagName": "v1.15.0",
9-
"sftSmartContractVersionTagName": "v0.6.0",
10-
"minterDappVersionTagName": "v7.4.1"
9+
"sftSmartContractVersionTagName": "v0.7.0",
10+
"minterDappVersionTagName": "v7.4.2"
1111
},
1212
"description": "Interacting with custom NFT/SFT-related smart contracts on the MultiversX blockchain",
1313
"bin": {
@@ -42,17 +42,18 @@
4242
"javascript",
4343
"typescript",
4444
"nft",
45+
"sft",
4546
"cli",
4647
"transaction",
4748
"interaction",
4849
"elrond"
4950
],
5051
"dependencies": {
51-
"@multiversx/sdk-core": "12.17.0",
52-
"@multiversx/sdk-network-providers": "2.2.0",
53-
"@multiversx/sdk-wallet": "4.2.0",
52+
"@multiversx/sdk-core": "12.18.0",
53+
"@multiversx/sdk-network-providers": "2.2.1",
54+
"@multiversx/sdk-wallet": "4.3.0",
5455
"adm-zip": "0.5.10",
55-
"axios": "1.6.5",
56+
"axios": "1.6.7",
5657
"bignumber.js": "9.1.2",
5758
"cosmiconfig": "9.0.0",
5859
"cross-fetch": "4.0.0",
@@ -65,15 +66,15 @@
6566
"devDependencies": {
6667
"@types/adm-zip": "0.5.5",
6768
"@types/cross-spawn": "6.0.6",
68-
"@types/node": "20.10.6",
69+
"@types/node": "20.11.17",
6970
"@types/prompts": "2.4.9",
70-
"@typescript-eslint/eslint-plugin": "6.18.0",
71-
"@typescript-eslint/parser": "6.18.0",
72-
"esbuild": "0.19.11",
71+
"@typescript-eslint/eslint-plugin": "6.21.0",
72+
"@typescript-eslint/parser": "6.21.0",
73+
"esbuild": "0.20.0",
7374
"eslint": "8.56.0",
7475
"eslint-config-prettier": "9.1.0",
75-
"eslint-plugin-prettier": "5.1.2",
76-
"prettier": "3.1.1",
76+
"eslint-plugin-prettier": "5.1.3",
77+
"prettier": "3.2.5",
7778
"rimraf": "5.0.5",
7879
"typescript": "5.3.3"
7980
}

src/config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ export const getSftBurnFunctionName =
362362
export const sftBurnGasLimit =
363363
customConfig?.config?.sftMinterSc?.burnGasLimit || 3000000;
364364

365+
// Gas limit required for giveaway transaction
366+
export const sftGiveawayTxBaseGasLimit =
367+
customConfig?.config?.sftMinterSc?.giveawayBaseGasLimit || 3500000;
368+
365369
// ⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡
366370
// Collection NFT owners
367371
// ⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡
@@ -459,6 +463,7 @@ export const sftTokenNonceLabel =
459463
'Provide token nonce (for example in TTSFT-d1d695-01 the 01 has to be provided):\n';
460464
export const amountToBuyLabel = 'Provide the amount of SFT to buy:\n';
461465
export const giveawayAddressLabel = `Provide the list of addresses.\nSeparate them with comma (","):\n`;
466+
export const sftGiveawayReceiversLabel = `Provide the list of receivers.\nExample: erd1...|01|10,erd1...|02|100 etc. (address|nonce|amount):\n`;
462467
export const giveawayTokensAmount = `Provide how many tokens per one address you want to give away. Max ${tokensPerOneGiveawayTx} in total because of the max gas limit per transaction:\n`;
463468
export const dropTokensAmountLabel =
464469
'Provide the amount of the tokens for the drop:\n';

src/nft-minter-fns.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
getNftSCAddressFromOutputOrConfig,
88
getNftAssignRolesTransaction,
99
getMintTransaction,
10-
getGiveawayTransaction,
10+
getNftGiveawayTransaction,
1111
getSetDropTransaction,
1212
getUnsetDropTransaction,
1313
getPauseMintingTransaction,
@@ -358,7 +358,7 @@ const giveaway = async () => {
358358
exit(9);
359359
}
360360

361-
const giveawayTx = getGiveawayTransaction(
361+
const giveawayTx = getNftGiveawayTransaction(
362362
signer.getAddress(),
363363
smartContract,
364364
giveawayTxBaseGasLimit,

src/sft-minter-fns.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import {
2525
getSftSetNewAmountLimitPerAddressTransaction,
2626
getSftMintTransaction,
2727
getSftBurnTransaction,
28+
getFileContents,
29+
getSftGiveawayTransaction,
2830
} from './utils';
2931
import prompts, { PromptObject } from 'prompts';
3032
import {
@@ -61,6 +63,9 @@ import {
6163
amountOfTokensToBurnLabel,
6264
sftCollectionProperties,
6365
sftSpecialRoles,
66+
giveawayFileRelativePath,
67+
sftGiveawayReceiversLabel,
68+
sftGiveawayTxBaseGasLimit,
6469
} from './config';
6570

6671
const nonceOnlyPromptQuestion: PromptObject[] = [
@@ -668,6 +673,66 @@ const getAmountPerAddressTotal = async () => {
668673
}
669674
};
670675

676+
const giveaway = async () => {
677+
const smartContractAddress = getSftSCAddressFromOutputOrConfig();
678+
679+
const promptQuestions: PromptObject[] = [
680+
{
681+
type: 'list',
682+
name: 'giveawayReceiversList',
683+
message: sftGiveawayReceiversLabel,
684+
validate: (value) =>
685+
value && value.length > 0 ? true : `Reguires at least one receiver!`,
686+
},
687+
];
688+
689+
try {
690+
const { smartContract, userAccount, signer, provider } =
691+
await setupSftSc(smartContractAddress);
692+
693+
const giveawayFile = getFileContents(giveawayFileRelativePath, {
694+
noExitOnError: true,
695+
});
696+
697+
let receivers = [];
698+
699+
if (giveawayFile) {
700+
console.log(' ');
701+
console.log(`Populating receivers from the file: giveaway.json.`);
702+
console.log(' ');
703+
await areYouSureAnswer();
704+
receivers = giveawayFile;
705+
} else {
706+
console.log(' ');
707+
console.log('There is no giveaway.json file with receivers.');
708+
console.log('You will be providing receivers by hand...');
709+
console.log(' ');
710+
await areYouSureAnswer();
711+
const { giveawayReceiversList } = await prompts(promptQuestions);
712+
const standarized = giveawayReceiversList.map((receiver: string) => {
713+
const split = receiver.split('|');
714+
return {
715+
address: split[0],
716+
nonce: split[1],
717+
amount: split[2],
718+
};
719+
});
720+
receivers = standarized;
721+
}
722+
723+
const giveawayTx = getSftGiveawayTransaction(
724+
signer.getAddress(),
725+
smartContract,
726+
sftGiveawayTxBaseGasLimit,
727+
receivers
728+
);
729+
730+
await commonTxOperations(giveawayTx, userAccount, signer, provider);
731+
} catch (e) {
732+
console.log((e as Error)?.message);
733+
}
734+
};
735+
671736
export const sftMinter = async (subcommand?: string) => {
672737
const COMMANDS = {
673738
issueCollectionToken: 'issue-collection-token',
@@ -681,6 +746,7 @@ export const sftMinter = async (subcommand?: string) => {
681746
pauseSelling: 'pause-selling',
682747
mint: 'mint',
683748
burn: 'burn',
749+
giveaway: 'giveaway',
684750
setNewAmountLimitPerAddress: 'set-new-amount-limit-per-address',
685751
getCollectionTokenName: 'get-collection-token-name',
686752
getCollectionTokenId: 'get-collection-token-id',
@@ -777,5 +843,8 @@ export const sftMinter = async (subcommand?: string) => {
777843
case COMMANDS.burn:
778844
burn();
779845
break;
846+
case COMMANDS.giveaway:
847+
giveaway();
848+
break;
780849
}
781850
};

src/utils.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
ITransactionOnNetwork,
2828
EnumType,
2929
EnumValue,
30+
Tuple,
3031
} from '@multiversx/sdk-core';
3132
import axios, { AxiosResponse } from 'axios';
3233
import { parseUserKey, UserSigner } from '@multiversx/sdk-wallet';
@@ -487,7 +488,7 @@ export const getMintTransaction = (
487488
}
488489
};
489490

490-
export const getGiveawayTransaction = (
491+
export const getNftGiveawayTransaction = (
491492
caller: UserAddress,
492493
contract: SmartContract,
493494
baseGasLimit: number,
@@ -1351,6 +1352,28 @@ export const getSftMaxAmountPerAddress = (nonce: string) => {
13511352
});
13521353
};
13531354

1355+
export const getSftGiveawayTransaction = (
1356+
caller: UserAddress,
1357+
contract: SmartContract,
1358+
baseGasLimit: number,
1359+
receivers: { address: string; nonce: string; amount: BigNumber }[]
1360+
) => {
1361+
const mintsCount = receivers.length;
1362+
return contract.call({
1363+
func: new ContractFunction(giveawayFunctionName),
1364+
gasLimit: baseGasLimit + 600_000 * (mintsCount - 1),
1365+
chainID: shortChainId[chain],
1366+
args: receivers.map((receiver) =>
1367+
Tuple.fromItems([
1368+
new AddressValue(Address.fromBech32(receiver.address)),
1369+
new U64Value(new BigNumber(receiver.nonce, 16)),
1370+
new BigUIntValue(new BigNumber(receiver.amount).valueOf()),
1371+
])
1372+
),
1373+
caller,
1374+
});
1375+
};
1376+
13541377
export const getTheCollectionIdAfterIssuing = (
13551378
transactionOnNetwork: ITransactionOnNetwork
13561379
) => {

0 commit comments

Comments
 (0)