Create a bot to cosign automatically transactions that require your account’s signature.
const cosignAggregateBondedTransaction = (transaction: AggregateTransaction, account: Account): CosignatureSignedTransaction => {
const cosignatureTransaction = CosignatureTransaction.create(transaction);
return account.signCosignatureTransaction(cosignatureTransaction);
};
const cosignAggregateBondedTransaction = (transaction, account) => {
const cosignatureTransaction = symbol_sdk_1.CosignatureTransaction.create(transaction);
return account.signCosignatureTransaction(cosignatureTransaction);
};
aggregateBondedAdded
channel using your account’s address.Note
To automatically sign aggregate bonded transactions that must be signed by multisig cosignatories, refer to the multisig address instead.See how to get multisig accounts where an account is cosignatory.
5. For each received transaction, check if you have signed it. At this point, you might want to do some extra checks, like verifying the contents of the transaction. Cosign each pending AggregateBondedTransaction using the previously created function.
CosignatureSignedTransaction
to the network using the TransactionHttp
repository.// replace with network type
const networkType = NetworkType.TEST_NET;
// replace with private key
const privateKey = '0000000000000000000000000000000000000000000000000000000000000000';
const account = Account.createFromPrivateKey(privateKey, networkType);
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
const listener = repositoryFactory.createListener();
listener.open().then(() => {
listener
.aggregateBondedAdded(account.address)
.pipe(
filter((_) => !_.signedByAccount(account.publicAccount)),
map((transaction) => cosignAggregateBondedTransaction(transaction, account)),
mergeMap((signedCosignatureTransaction) => {
listener.close();
return transactionHttp.announceAggregateBondedCosignature(signedCosignatureTransaction);
}),
)
.subscribe((announcedTransaction) => {
console.log(announcedTransaction);
listener.close();
}, (err) => console.error(err));
});
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
// replace with private key
const privateKey = '0000000000000000000000000000000000000000000000000000000000000000';
const account = symbol_sdk_1.Account.createFromPrivateKey(privateKey, networkType);
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
const listener = repositoryFactory.createListener();
listener.open().then(() => {
listener
.aggregateBondedAdded(account.address)
.pipe(operators_1.filter((_) => !_.signedByAccount(account.publicAccount)), operators_1.map((transaction) => cosignAggregateBondedTransaction(transaction, account)), operators_1.mergeMap((signedCosignatureTransaction) => {
listener.close();
return transactionHttp.announceAggregateBondedCosignature(signedCosignatureTransaction);
}))
.subscribe((announcedTransaction) => {
console.log(announcedTransaction);
listener.close();
}, (err) => console.error(err));
});
Extend the previous function to cosign transactions if they follow some constraints. For example, adapt your bot to only cosign aggregate transactions matching the following conditions:
symbol.xym
.Here you have a possible implementation:
const validTransaction = (transaction: Transaction, publicAccount: PublicAccount): boolean => {
return transaction instanceof TransferTransaction &&
transaction.signer!.equals(publicAccount) &&
transaction.mosaics.length === 1 &&
(transaction.mosaics[0].id.equals(new MosaicId('5E62990DCAC5BE8A') ||
transaction.mosaics[0].id.equals(new NamespaceId('symbol.xym')))) &&
transaction.mosaics[0].amount.compare(UInt64.fromUint(100 * Math.pow(10, 6))) < 0;
};
const cosignAggregateBondedTransaction = (transaction: AggregateTransaction, account: Account): CosignatureSignedTransaction => {
const cosignatureTransaction = CosignatureTransaction.create(transaction);
return account.signCosignatureTransaction(cosignatureTransaction);
};
// replace with network type
const networkType = NetworkType.TEST_NET;
// replace with private key
const privateKey = '0000000000000000000000000000000000000000000000000000000000000000';
const account = Account.createFromPrivateKey(privateKey, networkType);
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
const listener = repositoryFactory.createListener();
listener.open().then(() => {
listener
.aggregateBondedAdded(account.address)
.pipe(
filter((_) => _.innerTransactions.length === 2),
filter((_) => !_.signedByAccount(account.publicAccount)),
filter((_) => validTransaction(_.innerTransactions[0], account.publicAccount)
|| validTransaction(_.innerTransactions[1], account.publicAccount)),
map((transaction) => cosignAggregateBondedTransaction(transaction, account)),
mergeMap((signedCosignatureTransaction) => transactionHttp.announceAggregateBondedCosignature(signedCosignatureTransaction)),
)
.subscribe((announcedTransaction) => {
console.log(announcedTransaction);
listener.close();
},
(err) => console.error(err));
});
const validTransaction = (transaction, publicAccount) => {
return transaction instanceof symbol_sdk_1.TransferTransaction &&
transaction.signer.equals(publicAccount) &&
transaction.mosaics.length === 1 &&
(transaction.mosaics[0].id.equals(new symbol_sdk_1.MosaicId('5E62990DCAC5BE8A') ||
transaction.mosaics[0].id.equals(new symbol_sdk_1.NamespaceId('symbol.xym')))) &&
transaction.mosaics[0].amount.compare(symbol_sdk_1.UInt64.fromUint(100 * Math.pow(10, 6))) < 0;
};
const cosignAggregateBondedTransaction = (transaction, account) => {
const cosignatureTransaction = symbol_sdk_1.CosignatureTransaction.create(transaction);
return account.signCosignatureTransaction(cosignatureTransaction);
};
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
// replace with private key
const privateKey = '0000000000000000000000000000000000000000000000000000000000000000';
const account = symbol_sdk_1.Account.createFromPrivateKey(privateKey, networkType);
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
const listener = repositoryFactory.createListener();
listener.open().then(() => {
listener
.aggregateBondedAdded(account.address)
.pipe(operators_1.filter((_) => _.innerTransactions.length === 2), operators_1.filter((_) => !_.signedByAccount(account.publicAccount)), operators_1.filter((_) => validTransaction(_.innerTransactions[0], account.publicAccount)
|| validTransaction(_.innerTransactions[1], account.publicAccount)), operators_1.map((transaction) => cosignAggregateBondedTransaction(transaction, account)), operators_1.mergeMap((signedCosignatureTransaction) => transactionHttp.announceAggregateBondedCosignature(signedCosignatureTransaction)))
.subscribe((announcedTransaction) => {
console.log(announcedTransaction);
listener.close();
}, (err) => console.error(err));
});
Did you find what you were looking for? Give us your feedback.