Skip to content

Commit

Permalink
feat(mx): implement locking and claiming SFTs
Browse files Browse the repository at this point in the history
  • Loading branch information
imsk17 committed Oct 4, 2024
1 parent 781ced2 commit 6dc7d24
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 68 deletions.
194 changes: 129 additions & 65 deletions src/handlers/multiversx/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,15 @@ import {
AbiRegistry,
Account,
Address,
AddressType,
AddressValue,
BigUIntType,
BigUIntValue,
BytesType,
BytesValue,
ContractCallPayloadBuilder,
ContractFunction,
Field,
FieldDefinition,
ResultsParser,
SmartContract,
Struct,
StructType,
TokenTransfer,
Transaction,
TransactionPayload,
Expand All @@ -35,6 +30,7 @@ import { multiversXBridgeABI } from "../../contractsTypes/multiversx";
import { raise } from "../ton";
import { fetchHttpOrIpfs } from "../utils";
import {
StructClaimDataType,
TMultiversXHandler,
TMultiversXParams,
TMultiversXSigner,
Expand Down Expand Up @@ -179,6 +175,133 @@ export function multiversxHandler({
getProvider() {
return provider;
},
async claimSft(signer, claimData, sigs) {
const userAddress = Address.fromString(await signer.getAddress());
const userAccount = new Account(userAddress);
const userOnNetwork = await provider.getAccount(userAddress);
userAccount.update(userOnNetwork);

const imgUri = (await fetchHttpOrIpfs(claimData.metadata)).image;

const claimDataArgs = new Struct(StructClaimDataType, [
new Field(
new BytesValue(
Buffer.from(new Nonce(Number(claimData.tokenId)).hex(), "hex"),
),
"token_id",
),
new Field(
new BytesValue(Buffer.from(claimData.sourceChain)),
"source_chain",
),
new Field(
new BytesValue(Buffer.from(claimData.destinationChain)),
"destination_chain",
),
new Field(
new AddressValue(new Address(claimData.destinationUserAddress)),
"destination_user_address",
),
new Field(
new BytesValue(Buffer.from(claimData.sourceNftContractAddress)),
"source_nft_contract_address",
),
new Field(new BytesValue(Buffer.from(claimData.name)), "name"),
new Field(new BytesValue(Buffer.from(claimData.symbol)), "symbol"),
new Field(new BigUIntValue(Number(claimData.royalty)), "royalty"),
new Field(
new AddressValue(new Address(claimData.royaltyReceiver)),
"royalty_receiver",
),
new Field(new BytesValue(Buffer.from(claimData.metadata)), "attrs"),
new Field(
new BytesValue(Buffer.from(claimData.transactionHash)),
"transaction_hash",
),
new Field(new BigUIntValue(claimData.tokenAmount), "token_amount"),
new Field(new BytesValue(Buffer.from(claimData.nftType)), "nft_type"),
new Field(new BigUIntValue(claimData.fee), "fee"),
new Field(
new BytesValue(Buffer.from(claimData.lockTxChain)),
"lock_tx_chain",
),
new Field(new BytesValue(Buffer.from(imgUri)), "img_uri"),
]);
const data = [
claimDataArgs,

sigs.map((item) => {
return {
public_key: new AddressValue(
new Address(Buffer.from(item.signerAddress, "hex")),
),
sig: new BytesValue(
Buffer.from(item.signature.replace("0x", ""), "hex"),
),
};
}),
];
const transaction = multiversXBridgeContract.methods
.claimNft721(data)
.withSender(Address.fromString(await signer.getAddress()))
.withChainID("D")
.withGasLimit(6_000_000_00)
.withValue(new BigUIntValue("50000000000000000"))
.buildTransaction();
transaction.setNonce(userAccount.getNonceThenIncrement());
const signed = await signer.signTransaction(transaction);
const hash = await provider.sendTransaction(signed);
return { hash: () => hash, ret: hash };
},
async lockSft(signer, sourceNft, destinationChain, to, tokenId, amt) {
const ba = new Address(bridge);

const userAddress = Address.fromString(await signer.getAddress());

const userAccount = new Account(userAddress);
const userOnNetwork = await provider.getAccount(userAddress);
userAccount.update(userOnNetwork);

const collectionIdentifiers = `@${Buffer.from(sourceNft).toString(
"hex",
)}`;
const amount = `@${amt}`;
const nonce = new Nonce(Number(tokenId)).hex();
const noncec = `@${nonce}`;
const quantity = "@" + "01";
const destination_address = `@${ba.hex()}`;
const method = `@${Buffer.from("lock721").toString("hex")}`;
const token_id = `@${Buffer.from(`${sourceNft}-0${tokenId}`).toString(
"hex",
)}`;
const destination_chain = `@${Buffer.from(destinationChain).toString(
"hex",
)}`;
const destination_user_address = `@${Buffer.from(to).toString("hex")}`;
const source_nft_contract_address = collectionIdentifiers;

const tx3 = new Transaction({
data: new TransactionPayload(
`ESDTNFTTransfer${collectionIdentifiers}${noncec}${quantity}${destination_address}${method}${token_id}${destination_chain}${destination_user_address}${source_nft_contract_address}${amount}${noncec}`,
),
gasLimit: 600000000,
sender: Address.fromString(await signer.getAddress()),
receiver: Address.fromString(await signer.getAddress()),
chainID: "D",
});

tx3.setNonce(userAccount.getNonceThenIncrement());

const signed = await signer.signTransaction(tx3);

const txHash = await provider.sendTransaction(signed);
return {
tx: txHash,
hash() {
return txHash;
},
};
},
async readClaimed721Event(hash) {
await waitForTransaction(hash);
const response = (
Expand Down Expand Up @@ -408,66 +531,7 @@ export function multiversxHandler({

const imgUri = (await fetchHttpOrIpfs(claimData.metadata)).image;

const structClaimData = new StructType("ClaimData", [
new FieldDefinition("token_id", "name of the nft", new BytesType()),
new FieldDefinition(
"source_chain",
"attributes of the nft",
new BytesType(),
),
new FieldDefinition(
"destination_chain",
"attributes of the nft",
new BytesType(),
),
new FieldDefinition(
"destination_user_address",
"attributes of the nft",
new AddressType(),
),
new FieldDefinition(
"source_nft_contract_address",
"attributes of the nft",
new BytesType(),
),
new FieldDefinition("name", "attributes of the nft", new BytesType()),
new FieldDefinition("symbol", "attributes of the nft", new BytesType()),
new FieldDefinition(
"royalty",
"attributes of the nft",
new BigUIntType(),
),
new FieldDefinition(
"royalty_receiver",
"attributes of the nft",
new AddressType(),
),
new FieldDefinition("attrs", "attributes of the nft", new BytesType()),
new FieldDefinition(
"transaction_hash",
"attributes of the nft",
new BytesType(),
),
new FieldDefinition(
"token_amount",
"attributes of the nft",
new BigUIntType(),
),
new FieldDefinition(
"nft_type",
"attributes of the nft",
new BytesType(),
),
new FieldDefinition("fee", "attributes of the nft", new BigUIntType()),
new FieldDefinition(
"lock_tx_chain",
"Chain identifier on which nft was locked",
new BytesType(),
),
new FieldDefinition("img_uri", "uri of the image", new BytesType()),
]);

const claimDataArgs = new Struct(structClaimData, [
const claimDataArgs = new Struct(StructClaimDataType, [
new Field(
new BytesValue(
Buffer.from(new Nonce(Number(claimData.tokenId)).hex(), "hex"),
Expand Down
60 changes: 57 additions & 3 deletions src/handlers/multiversx/types.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { Transaction } from "@multiversx/sdk-core/out";
import {
AddressType,
BigUIntType,
BytesType,
FieldDefinition,
StructType,
Transaction,
} from "@multiversx/sdk-core/out";
import { INetworkProvider } from "@multiversx/sdk-network-providers/out/interface";
import { BridgeStorage } from "../../contractsTypes/evm";
import {
DeployNFTCollection,
MintNft,
ReadClaimed721Event,
ReadClaimed1155Event,
TSingularNftChain,
TNftChain,
} from "../types";

// Custom Interface because there is no such signer interface in mx-sdk.
Expand Down Expand Up @@ -48,7 +55,7 @@ export type NftIssueArgs = {
readonly ticker: string;
};

export type TMultiversXHandler = TSingularNftChain<
export type TMultiversXHandler = TNftChain<
TMultiversXSigner,
TMultiversXClaimArgs,
unknown,
Expand Down Expand Up @@ -83,3 +90,50 @@ export type TMultiversXParams = {
chainId: string;
identifier: string;
};

export const StructClaimDataType = new StructType("ClaimData", [
new FieldDefinition("token_id", "name of the nft", new BytesType()),
new FieldDefinition("source_chain", "attributes of the nft", new BytesType()),
new FieldDefinition(
"destination_chain",
"attributes of the nft",
new BytesType(),
),
new FieldDefinition(
"destination_user_address",
"attributes of the nft",
new AddressType(),
),
new FieldDefinition(
"source_nft_contract_address",
"attributes of the nft",
new BytesType(),
),
new FieldDefinition("name", "attributes of the nft", new BytesType()),
new FieldDefinition("symbol", "attributes of the nft", new BytesType()),
new FieldDefinition("royalty", "attributes of the nft", new BigUIntType()),
new FieldDefinition(
"royalty_receiver",
"attributes of the nft",
new AddressType(),
),
new FieldDefinition("attrs", "attributes of the nft", new BytesType()),
new FieldDefinition(
"transaction_hash",
"attributes of the nft",
new BytesType(),
),
new FieldDefinition(
"token_amount",
"attributes of the nft",
new BigUIntType(),
),
new FieldDefinition("nft_type", "attributes of the nft", new BytesType()),
new FieldDefinition("fee", "attributes of the nft", new BigUIntType()),
new FieldDefinition(
"lock_tx_chain",
"Chain identifier on which nft was locked",
new BytesType(),
),
new FieldDefinition("img_uri", "uri of the image", new BytesType()),
]);

0 comments on commit 6dc7d24

Please sign in to comment.