-
Notifications
You must be signed in to change notification settings - Fork 8
Metadata Transactions
Chun Lam edited this page Feb 21, 2024
·
3 revisions
import { MetadataHttp, MetadataQueryParams, MetadataType, MosaicId, NamespaceId, PublicAccount,
AccountMetadataTransaction, MosaicMetadataTransaction, NamespaceMetadataTransaction, Listener,
Deadline, NetworkType, KeyGenerator, AggregateTransaction, Account, HashLockTransaction,
NetworkCurrencyMosaic, UInt64, TransactionHttp } from "tsjs-xpx-chain-sdk";
const API_URL = 'http://localhost:3000';
const networkType = NetworkType.TEST_NET;
const generationHash = "56D112C98F7A7E34D1AEDC4BD01BC06CA2276DD546A93E36690B785E82439CA9"; // from block 1
const metadataHttp = new MetadataHttp(API_URL);
const transactionHttp = new TransactionHttp(API_URL);
let listener = new Listener(API_URL);
const signerAccount = Account.createFromPrivateKey(
'<your_privateKey>',
networkType, 1);
const targetPublicAccount = PublicAccount.createFromPublicKey("F06FE22FBA1E116B8F0E673BA4EE424B16BD6EA7548ED259F3DCEBF8D74C49B9", networkType, 1);
const sendAccountMedataTransaction = () =>{
// search targetKey, account type metadata
let metadataQueryParams = new MetadataQueryParams();
metadataQueryParams.metadataType = MetadataType.ACCOUNT;
metadataQueryParams.targetKey = targetPublicAccount;
metadataQueryParams.scopedMetadataKey = KeyGenerator.generateUInt64Key("myKey");
metadataHttp.searchMetadata(metadataQueryParams).subscribe({
next: metadataSearchResult => {
let oldMetadataValue = ""; // set empty previous value
if(metadataSearchResult.metadataEntries.length){
oldMetadataValue = metadataSearchResult.metadataEntries[0].value;
}
let accountMetadataTxn = AccountMetadataTransaction.create(
Deadline.create(),
targetPublicAccount,
"myKey",
"newValue",
oldMetadataValue,
networkType
);
// will need to use AggregateBonded, it only work that way
let aggregateBondedTxn = AggregateTransaction.createBondedV1(
Deadline.create(),
[
accountMetadataTxn.toAggregateV1(signerAccount.publicAccount)
],
networkType
)
let signedAbtTransaction = signerAccount.preV2Sign(aggregateBondedTxn, generationHash);
let lockhashTx = HashLockTransaction.create(
Deadline.create(),
NetworkCurrencyMosaic.createRelative(10), // 10 XPX to lock
UInt64.fromUint(10000), // duration in block
signedAbtTransaction,
networkType
);
let signedLockHashTransaction = signerAccount.preV2Sign(lockhashTx, generationHash);
listener.open().then(()=>{
let initial = 0;
let announced = false;
let lockHashConfirmed = false;
let lockhashConfirmedAt = 0;
console.log("Listening");
let confirmedListener = listener.confirmed(signerAccount.address).subscribe((confirmedTx)=>{
if(confirmedTx.transactionInfo!.hash === signedLockHashTransaction.hash){
lockHashConfirmed = true;
lockhashConfirmedAt = confirmedTx.transactionInfo!.height.compact();
console.log("Lockhash Confirmed", lockhashConfirmedAt);
}
else if(confirmedTx.transactionInfo!.hash === signedAbtTransaction.hash){
console.log("ABT Confirmed");
confirmedListener.unsubscribe();
newBlockListener.unsubscribe();
listener.close();
}
});
let newBlockListener = listener.newBlock().subscribe((blockInfo)=>{
console.log(blockInfo.height.compact());
if(initial === 0){
initial = blockInfo.height.compact();
}
else if(lockhashConfirmedAt && ( lockhashConfirmedAt + 1 < blockInfo.height.compact()) && lockHashConfirmed && !announced){
transactionHttp.announceAggregateBonded(signedAbtTransaction);
announced = true;
console.log("announced");
confirmedListener.unsubscribe();
newBlockListener.unsubscribe();
listener.close();
// wait for confirmation or cosign of the transaction
}
});
transactionHttp.announce(signedLockHashTransaction).subscribe(
(message)=>{
console.log(message);
},
(error)=>{
console.log(error);
}
);
});
}, error: error => {
console.error(error);
}
})
}
const sendMosaicMedataTransaction = () =>{
const xpxMosaicId = new MosaicId("13bfc518e40549d7");
// search mosaic type metadata
let metadataQueryParams = new MetadataQueryParams();
metadataQueryParams.metadataType = MetadataType.MOSAIC;
metadataQueryParams.targetId = xpxMosaicId;
metadataQueryParams.scopedMetadataKey = KeyGenerator.generateUInt64Key("myKey");
metadataHttp.searchMetadata(metadataQueryParams).subscribe({
next: metadataSearchResult => {
let oldMetadataValue = ""; // set empty previous value
if(metadataSearchResult.metadataEntries.length){
oldMetadataValue = metadataSearchResult.metadataEntries[0].value;
}
let mosaicMetadataTxn = MosaicMetadataTransaction.create(
Deadline.create(),
targetPublicAccount,
xpxMosaicId,
"myKey",
"newValue",
oldMetadataValue,
networkType
);
// will need to use AggregateBonded, it only work that way
let aggregateBondedTxn = AggregateTransaction.createBondedV1(
Deadline.create(),
[
mosaicMetadataTxn.toAggregateV1(signerAccount.publicAccount)
],
networkType
)
let signedAbtTransaction = signerAccount.preV2Sign(aggregateBondedTxn, generationHash);
let lockhashTx = HashLockTransaction.create(
Deadline.create(),
NetworkCurrencyMosaic.createRelative(10), // 10 XPX to lock
UInt64.fromUint(10000), // duration in block
signedAbtTransaction,
networkType
);
let signedLockHashTransaction = signerAccount.preV2Sign(lockhashTx, generationHash);
listener.open().then(()=>{
let initial = 0;
let announced = false;
let lockHashConfirmed = false;
let lockhashConfirmedAt = 0;
console.log("Listening");
let confirmedListener = listener.confirmed(signerAccount.address).subscribe((confirmedTx)=>{
if(confirmedTx.transactionInfo!.hash === signedLockHashTransaction.hash){
lockHashConfirmed = true;
lockhashConfirmedAt = confirmedTx.transactionInfo!.height.compact();
console.log("Lockhash Confirmed", lockhashConfirmedAt);
}
else if(confirmedTx.transactionInfo!.hash === signedAbtTransaction.hash){
console.log("ABT Confirmed");
confirmedListener.unsubscribe();
newBlockListener.unsubscribe();
listener.close();
}
});
let newBlockListener = listener.newBlock().subscribe((blockInfo)=>{
console.log(blockInfo.height.compact());
if(initial === 0){
initial = blockInfo.height.compact();
}
else if(lockhashConfirmedAt && ( lockhashConfirmedAt + 1 < blockInfo.height.compact()) && lockHashConfirmed && !announced){
transactionHttp.announceAggregateBonded(signedAbtTransaction);
announced = true;
console.log("announced");
confirmedListener.unsubscribe();
newBlockListener.unsubscribe();
listener.close();
// wait for confirmation or cosign of the transaction
}
});
transactionHttp.announce(signedLockHashTransaction).subscribe(
(message)=>{
console.log(message);
},
(error)=>{
console.log(error);
}
);
});
}, error: error => {
console.error(error);
}
})
}
const sendNamespaceMedataTransaction = () =>{
const xpxNamespaceId = new NamespaceId("prx.xpx");
// search namespace type metadata
let metadataQueryParams = new MetadataQueryParams();
metadataQueryParams.metadataType = MetadataType.NAMESPACE;
metadataQueryParams.targetId = xpxNamespaceId;
metadataQueryParams.scopedMetadataKey = KeyGenerator.generateUInt64Key("myKey");
metadataHttp.searchMetadata(metadataQueryParams).subscribe({
next: metadataSearchResult => {
let oldMetadataValue = ""; // set empty previous value
if(metadataSearchResult.metadataEntries.length){
oldMetadataValue = metadataSearchResult.metadataEntries[0].value;
}
let namespaceMetadataTxn = NamespaceMetadataTransaction.create(
Deadline.create(),
targetPublicAccount,
xpxNamespaceId,
"myKey",
"newValue",
oldMetadataValue,
networkType
);
// will need to use AggregateBonded, it only work that way
let aggregateBondedTxn = AggregateTransaction.createBondedV1(
Deadline.create(),
[
namespaceMetadataTxn.toAggregateV1(signerAccount.publicAccount)
],
networkType
)
let signedAbtTransaction = signerAccount.preV2Sign(aggregateBondedTxn, generationHash);
let lockhashTx = HashLockTransaction.create(
Deadline.create(),
NetworkCurrencyMosaic.createRelative(10), // 10 XPX to lock
UInt64.fromUint(10000), // duration in block
signedAbtTransaction,
networkType
);
let signedLockHashTransaction = signerAccount.preV2Sign(lockhashTx, generationHash);
listener.open().then(()=>{
let initial = 0;
let announced = false;
let lockHashConfirmed = false;
let lockhashConfirmedAt = 0;
console.log("Listening");
let confirmedListener = listener.confirmed(signerAccount.address).subscribe((confirmedTx)=>{
if(confirmedTx.transactionInfo!.hash === signedLockHashTransaction.hash){
lockHashConfirmed = true;
lockhashConfirmedAt = confirmedTx.transactionInfo!.height.compact();
console.log("Lockhash Confirmed", lockhashConfirmedAt);
}
else if(confirmedTx.transactionInfo!.hash === signedAbtTransaction.hash){
console.log("ABT Confirmed");
confirmedListener.unsubscribe();
newBlockListener.unsubscribe();
listener.close();
}
});
let newBlockListener = listener.newBlock().subscribe((blockInfo)=>{
console.log(blockInfo.height.compact());
if(initial === 0){
initial = blockInfo.height.compact();
}
else if(lockhashConfirmedAt && ( lockhashConfirmedAt + 1 < blockInfo.height.compact()) && lockHashConfirmed && !announced){
transactionHttp.announceAggregateBonded(signedAbtTransaction);
announced = true;
console.log("announced");
confirmedListener.unsubscribe();
newBlockListener.unsubscribe();
listener.close();
// wait for confirmation or cosign of the transaction
}
});
transactionHttp.announce(signedLockHashTransaction).subscribe({
next: (message)=>{
console.log(message);
},
error: (error)=>{
console.log(error);
}
});
});
}, error: error => {
console.error(error);
}
})
}