Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add more filters for transfer tokens for the evm action - MEED-…
Browse files Browse the repository at this point in the history
…5850 - Meeds-io/MIPs#118 (#27)

This change will add more filters for transfer tokens for the evm action.
MayTekayaa authored and boubaker committed Apr 25, 2024

Verified

This commit was signed with the committer’s verified signature.
targos Michaël Zasso
1 parent aeadb3a commit ab1895f
Showing 9 changed files with 161 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ public String getEventType() {
}

public List<String> getTriggers() {
return List.of(Utils.HOLD_TOKEN_EVENT);
return List.of(Utils.TRANSFER_TOKEN_EVENT);
}

@Override
Original file line number Diff line number Diff line change
@@ -15,8 +15,10 @@
*/
package io.meeds.evm.gamification.scheduling.task;

import java.math.BigInteger;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import io.meeds.common.ContainerTransactional;
import io.meeds.evm.gamification.model.TokenTransferEvent;
@@ -81,10 +83,14 @@ public synchronized void listenTokenTransfer() {
.toList();
if (CollectionUtils.isNotEmpty(filteredRules)) {
filteredRules.forEach(rule -> {
BigInteger minAmount;
String recipientAddress;
BigInteger base = new BigInteger("10");
String blockchainNetwork = rule.getEvent().getProperties().get(Utils.BLOCKCHAIN_NETWORK);
String contractAddress = rule.getEvent().getProperties().get(Utils.CONTRACT_ADDRESS);
String tokenName = rule.getEvent().getProperties().get(Utils.NAME);
String tokenSymbol = rule.getEvent().getProperties().get(Utils.SYMBOL);
Integer tokenDecimals = Integer.parseInt(rule.getEvent().getProperties().get(Utils.DECIMALS));
long lastBlock = blockchainService.getLastBlock(blockchainNetwork);
long lastCheckedBlock = getLastCheckedBlock(contractAddress);
if (lastCheckedBlock == 0) {
@@ -97,24 +103,36 @@ public synchronized void listenTokenTransfer() {
lastBlock,
contractAddress,
blockchainNetwork);
if (!CollectionUtils.isEmpty(events)) {
events.forEach(event -> {
try {
EvmTrigger evmTrigger = new EvmTrigger();
evmTrigger.setTrigger(Utils.HOLD_TOKEN_EVENT);
evmTrigger.setType(Utils.CONNECTOR_NAME);
evmTrigger.setWalletAddress(event.getTo());
evmTrigger.setTransactionHash(event.getTransactionHash());
evmTrigger.setContractAddress(contractAddress);
evmTrigger.setBlockchainNetwork(blockchainNetwork);
evmTrigger.setTokenName(tokenName);
evmTrigger.setTokenSymbol(tokenSymbol);
evmTriggerService.handleTriggerAsync(evmTrigger);
} catch (Exception e) {
LOG.warn("Error broadcasting event '" + event, e);
}
});
}
if(!CollectionUtils.isEmpty(events) && StringUtils.isNotBlank(rule.getEvent().getProperties().get(Utils.MIN_AMOUNT))) {
minAmount = base.pow(tokenDecimals).multiply(new BigInteger(rule.getEvent().getProperties().get(Utils.MIN_AMOUNT)));
events = events.stream()
.filter(event -> event.getAmount().compareTo(minAmount) > 0)
.collect(Collectors.toSet());
}
if(!CollectionUtils.isEmpty(events) && StringUtils.isNotBlank(rule.getEvent().getProperties().get(Utils.RECIPIENT_ADDRESS))) {
recipientAddress = rule.getEvent().getProperties().get(Utils.RECIPIENT_ADDRESS);
events = events.stream()
.filter(event -> recipientAddress.toUpperCase().equals(event.getTo().toUpperCase()))
.collect(Collectors.toSet());
}
if (!CollectionUtils.isEmpty(events)) {
events.forEach(event -> {
try {
EvmTrigger evmTrigger = new EvmTrigger();
evmTrigger.setTrigger(Utils.TRANSFER_TOKEN_EVENT);
evmTrigger.setType(Utils.CONNECTOR_NAME);
evmTrigger.setWalletAddress(event.getTo());
evmTrigger.setTransactionHash(event.getTransactionHash());
evmTrigger.setContractAddress(contractAddress);
evmTrigger.setBlockchainNetwork(blockchainNetwork);
evmTrigger.setTokenName(tokenName);
evmTrigger.setTokenSymbol(tokenSymbol);
evmTriggerService.handleTriggerAsync(evmTrigger);
} catch (Exception e) {
LOG.warn("Error broadcasting event '" + event, e);
}
});
}
saveLastCheckedBlock(lastBlock, contractAddress);
LOG.info("End listening erc20 token transfers");
});
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ public class Utils {

public static final String CONNECTOR_NAME = "evm";

public static final String HOLD_TOKEN_EVENT = "holdToken";
public static final String TRANSFER_TOKEN_EVENT = "transferToken";

public static final String WALLET_ADDRESS = "walletAddress";

@@ -34,6 +34,12 @@ public class Utils {

public static final String SYMBOL = "tokenSymbol";

public static final String DECIMALS = "tokenDecimals";

public static final String MIN_AMOUNT = "minAmount";

public static final String RECIPIENT_ADDRESS = "recipientAddress";

public static final String TRANSACTION_HASH = "transactionHash";

private Utils() {
Original file line number Diff line number Diff line change
@@ -25,21 +25,21 @@
<external-component-plugins>
<target-component>io.meeds.gamification.service.EventRegistry</target-component>
<component-plugin>
<name>HoldToken</name>
<name>TransferToken</name>
<set-method>addPlugin</set-method>
<type>io.meeds.gamification.plugin.EventConfigPlugin</type>
<init-params>
<object-param>
<name>event</name>
<object type="io.meeds.gamification.model.EventDTO">
<field name="title">
<string>holdToken</string>
<string>transferToken</string>
</field>
<field name="type">
<string>evm</string>
</field>
<field name="trigger">
<string>holdToken</string>
<string>transferToken</string>
</field>
</object>
</object-param>
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
gamification.event.title.holdToken=EVM: Hold Token
gamification.event.title.transferToken=Transfer a Token
gamification.event.form.networks=Blockchain
gamification.event.form.contractAddress=Smart Contract
gamification.event.form.contractAddress.placeholder=Enter the contract address
gamification.event.form.contractAddress=Token Address
gamification.event.form.contractAddress.placeholder=Enter the token address
gamification.event.form.contractAddress.tooltip=Verif addresss on {0}
gamification.event.form.recipientAddress=Recipient
gamification.event.form.recipientAddress.placeholder=Enter the recipient address
gamification.event.form.minAmount=Minimum amount
gamification.event.form.minAmount.placeholder=Enter the minimum amount
gamification.event.detail.invalidContractAddress.error=Please enter a valid contract address
gamification.event.detail.invalidERC20ContractAddress.error=No smart contract found at this address
gamification.event.detail.verifyToken.message=Click the Checkmark icon to verify this address
gamification.event.detail.display.holdToken=Contract address token
gamification.event.detail.display.transferToken=Contract address token

gamification.admin.evm.label.description=Listen to any smart contract transaction on Ethereum Virtual Machine blockchains
Original file line number Diff line number Diff line change
@@ -29,6 +29,18 @@
{{ contractAddress }}
</div>
</a>
<div class="subtitle-1 font-weight-bold mb-2 mt-4">
{{ $t('gamification.event.form.recipientAddress') }}
</div>
<div class="text-font-size align-self-start">
{{ recipientAddress }}
</div>
<div class="subtitle-1 font-weight-bold mb-2 mt-4">
{{ $t('gamification.event.form.minAmount') }}
</div>
<div class="text-font-size align-self-start">
{{ minAmount }}
</div>
</div>
</template>
<script>
@@ -50,8 +62,24 @@ export default {
titleTriggerProps() {
return this.$t(`gamification.event.detail.display.${this.trigger}`);
},
blockchainNetwork() {
return this.properties?.blockchainNetwork;
},
explorerLink() {
return `https://polygonscan.com/address/${this.contractAddress}`;
const url = this.blockchainNetwork?.substring(this.blockchainNetwork.indexOf('//') + 2, this.blockchainNetwork.indexOf('.g.alchemy.com'));
switch (url) {
case 'polygon-mainnet': return `https://polygonscan.com/address/${this.contractAddress}`;
case 'polygon-mumbai': return `https://mumbai.polygonscan.com/address/${this.contractAddress}`;
case 'eth-mainnet': return `https://etherscan.io/address/${this.contractAddress}`;
case 'eth-sepolia': return `https://sepolia.etherscan.io/address/${this.contractAddress}`;
}
return '';
},
minAmount() {
return this.properties?.minAmount;
},
recipientAddress() {
return this.properties?.recipientAddress;
}
},
};
Original file line number Diff line number Diff line change
@@ -104,6 +104,32 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
<span v-if="isInValidAddressFormat" class="error--text">{{ $t('gamification.event.detail.invalidContractAddress.error') }}</span>
<span v-else-if="isInvalidERC20Address" class="error--text">{{ $t('gamification.event.detail.invalidERC20ContractAddress.error') }}</span>
<span v-else-if="emptyERC20Token">{{ $t('gamification.event.detail.verifyToken.message') }}</span>
<div v-if="erc20Token">
<v-card-text class="px-0 dark-grey-color font-weight-bold">
{{ $t('gamification.event.form.recipientAddress') }}
</v-card-text>
<v-text-field
ref="recipientAddress"
v-model="recipientAddress"
:placeholder="$t('gamification.event.form.recipientAddress.placeholder')"
class="pa-0"
type="text"
outlined
dense
@change="selectedRecipient" />
<v-card-text class="px-0 dark-grey-color font-weight-bold">
{{ $t('gamification.event.form.minAmount') }}
</v-card-text>
<v-text-field
ref="minAmount"
v-model="minAmount"
:placeholder="$t('gamification.event.form.minAmount.placeholder')"
class="pa-0"
type="text"
outlined
dense
@change="selectedAmount" />
</div>
</template>
</div>
</template>
@@ -203,21 +229,12 @@ export default {
return this.$evmConnectorService.getTokenDetailsByAddress({contractAddress: this.contractAddress, blockchainNetwork: this.selected?.providerUrl})
.then(token => {
this.erc20Token = token;
this.eventProperties = {
contractAddress: this.contractAddress,
blockchainNetwork: this.selected?.providerUrl,
tokenName: token.name,
tokenSymbol: token.symbol
};
})
.then(() => this.loading = false )
.catch(() => {
this.isValidERC20Address = false;
this.erc20Token = null;
this.loading = false;
})
.finally(() => {
this.submitEventProperties();
});
},
resetERC20Token() {
@@ -237,13 +254,61 @@ export default {
name: this.properties?.tokenName,
symbol: this.properties?.tokenSymbol
};
this.minAmount = this.properties?.minAmount;
this.recipientAddress = this.properties?.recipientAddress;
this.readOnly = true;
this.isValidAddress = true;
}
document.dispatchEvent(new CustomEvent('event-form-unfilled'));
this.loadingNetworks = false;
});
},
selectedAmount(minAmount) {
if (this.recipientAddress) {
this.eventProperties = {
contractAddress: this.contractAddress,
blockchainNetwork: this.selected?.providerUrl,
tokenName: this.erc20Token.name,
tokenSymbol: this.erc20Token.symbol,
tokenDecimals: this.erc20Token.decimals,
recipientAddress: this.recipientAddress,
minAmount: minAmount
};
} else {
this.eventProperties = {
contractAddress: this.contractAddress,
blockchainNetwork: this.selected?.providerUrl,
tokenName: this.erc20Token.name,
tokenSymbol: this.erc20Token.symbol,
tokenDecimals: this.erc20Token.decimals,
minAmount: minAmount
};
}
document.dispatchEvent(new CustomEvent('event-form-filled', {detail: this.eventProperties}));
},
selectedRecipient(recipientAddress) {
if (this.minAmount) {
this.eventProperties = {
contractAddress: this.contractAddress,
blockchainNetwork: this.selected?.providerUrl,
tokenName: this.erc20Token.name,
tokenSymbol: this.erc20Token.symbol,
tokenDecimals: this.erc20Token.decimals,
recipientAddress: recipientAddress,
minAmount: this.minAmount
};
} else {
this.eventProperties = {
contractAddress: this.contractAddress,
blockchainNetwork: this.selected?.providerUrl,
tokenName: this.erc20Token.name,
tokenSymbol: this.erc20Token.symbol,
tokenDecimals: this.erc20Token.decimals,
recipientAddress: recipientAddress
};
}
document.dispatchEvent(new CustomEvent('event-form-filled', {detail: this.eventProperties}));
}
},
}
};
</script>
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ export function init() {
name: 'evm',
vueComponent: Vue.options.components['evm-connector-event'],
isEnabled: (params) => [
'holdToken',
'transferToken',
].includes(params?.trigger),
});
}
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ export function init() {
rank: 60,
image: '/gamification-evm/images/EVM.png',
match: (actionLabel) => [
'holdToken',
'transferToken',
].includes(actionLabel),
getLink: realization => {
if (realization.objectType === 'evm' && realization.objectId !== '') {

0 comments on commit ab1895f

Please sign in to comment.