-
Notifications
You must be signed in to change notification settings - Fork 8
Modify multisig account transaction
Chun Lam edited this page Feb 21, 2024
·
4 revisions
import { Deadline, Account, NetworkType, ModifyMultisigAccountTransaction,
MultisigCosignatoryModification, MultisigCosignatoryModificationType,
TransferTransaction, PlainMessage, CosignatureTransaction, AggregateTransaction,
HashLockTransaction, Mosaic, UInt64, MosaicId, NamespaceId
} from 'tsjs-xpx-chain-sdk';
import { Network } from '../utils';
const network = new Network('http://localhost:3000');
const NETWORK_TYPE = NetworkType.MIJIN_TEST;
const seeding = Account.createFromPrivateKey(
'28FCECEA252231D2C86E1BCF7DD541552BDBBEFBB09324758B3AC199B4AA7B78',
NetworkType.MIJIN_TEST, 1);
const toBecomeMultisig = Account.createFromPrivateKey(
'0123456789012345678901234567890123456789012345678901234567890123',
NetworkType.MIJIN_TEST, 1);
const cosignatory1 = Account.createFromPrivateKey(
'1123456789012345678901234567890123456789012345678901234567890123',
NetworkType.MIJIN_TEST, 1);
const cosignatory2 = Account.createFromPrivateKey(
'2123456789012345678901234567890123456789012345678901234567890123',
NetworkType.MIJIN_TEST, 1);
const cosignatory3 = Account.createFromPrivateKey(
'3123456789012345678901234567890123456789012345678901234567890123',
NetworkType.MIJIN_TEST, 1);
const hundredXpx = new Mosaic(new NamespaceId("prx.xpx"), UInt64.fromUint(100 * 1000000));
network.networkProperties.then(networkProperties => {
const modifyMultisigAccountTx = ModifyMultisigAccountTransaction.create(
Deadline.create(),
2,
2,
[
new MultisigCosignatoryModification(MultisigCosignatoryModificationType.Add, cosignatory1.publicAccount),
new MultisigCosignatoryModification(MultisigCosignatoryModificationType.Add, cosignatory2.publicAccount),
new MultisigCosignatoryModification(MultisigCosignatoryModificationType.Add, cosignatory3.publicAccount),
],
NetworkType.MIJIN_TEST
)
const aggregateBonded = AggregateTransaction.createBondedV1(
Deadline.create(),
[modifyMultisigAccountTx.toAggregateV1(toBecomeMultisig.publicAccount)],
NETWORK_TYPE);
const signedAggregateBonded = toBecomeMultisig.preV2Sign(aggregateBonded, networkProperties.generationHash);
const hashLock = HashLockTransaction.create(
Deadline.create(),
new Mosaic(new NamespaceId("prx.xpx"), UInt64.fromUint(10 * 1000000)),
UInt64.fromUint(50),
signedAggregateBonded,
NETWORK_TYPE
)
const signedHashLock = toBecomeMultisig.preV2Sign(hashLock, networkProperties.generationHash);
// make sure all soon-to-be cosignatories have public keys and some xpx, so they can be added as cosignatories
network.api.listener.open().then(() => {
Promise.all([
network.announceAndWaitForConfirmation(
seeding.preV2Sign(
TransferTransaction.create(Deadline.create(), toBecomeMultisig.address, [hundredXpx], PlainMessage.create('Good luck!'), NETWORK_TYPE),
networkProperties.generationHash
)
),
network.announceAndWaitForConfirmation(
seeding.preV2Sign(
TransferTransaction.create(Deadline.create(), cosignatory1.address, [hundredXpx], PlainMessage.create('Good luck!'), NETWORK_TYPE),
networkProperties.generationHash
)
),
network.announceAndWaitForConfirmation(
seeding.preV2Sign(
TransferTransaction.create(Deadline.create(), cosignatory2.address, [hundredXpx], PlainMessage.create('Good luck!'), NETWORK_TYPE),
networkProperties.generationHash
)
),
network.announceAndWaitForConfirmation(
seeding.preV2Sign(
TransferTransaction.create(Deadline.create(), cosignatory3.address, [hundredXpx], PlainMessage.create('Good luck!'), NETWORK_TYPE),
networkProperties.generationHash
)
)]
).then(_ => {
Promise.all([
network.announceAndWaitForConfirmation(
cosignatory1.preV2Sign(
TransferTransaction.create(Deadline.create(), cosignatory1.address, [], PlainMessage.create('get public key'), NETWORK_TYPE),
networkProperties.generationHash
)
),
network.announceAndWaitForConfirmation(
cosignatory2.preV2Sign(
TransferTransaction.create(Deadline.create(), cosignatory2.address, [], PlainMessage.create('get public key'), NETWORK_TYPE),
networkProperties.generationHash
)
),
network.announceAndWaitForConfirmation(
cosignatory3.preV2Sign(
TransferTransaction.create(Deadline.create(), cosignatory3.address, [], PlainMessage.create('get public key'), NETWORK_TYPE),
networkProperties.generationHash
)
)
]).then(_ => {
// following listener code should be executed by other clients - one for each opt-in confirmation
network.api.listener.open().then(() => {
const sub1 = network.api.listener.aggregateBondedAdded(cosignatory1.address).subscribe(aggregateTransaction => {
if (! aggregateTransaction.signedByAccount(cosignatory1.publicAccount)) {
sub1.unsubscribe();
network.api.transaction.announceAggregateBondedCosignature(
cosignatory1.preV2SignCosignatureTransaction(CosignatureTransaction.create(aggregateTransaction))
);
console.log('Cosignatory 1 signed and announced.')
}
});
const sub2 = network.api.listener.aggregateBondedAdded(cosignatory2.address).subscribe(aggregateTransaction => {
if (! aggregateTransaction.signedByAccount(cosignatory2.publicAccount)) {
sub2.unsubscribe();
network.api.transaction.announceAggregateBondedCosignature(
cosignatory2.preV2SignCosignatureTransaction(CosignatureTransaction.create(aggregateTransaction))
);
console.log('Cosignatory 2 signed and announced.')
}
});
const sub3 = network.api.listener.aggregateBondedAdded(cosignatory3.address).subscribe(aggregateTransaction => {
if (! aggregateTransaction.signedByAccount(cosignatory3.publicAccount)) {
sub3.unsubscribe();
network.api.transaction.announceAggregateBondedCosignature(
cosignatory3.preV2SignCosignatureTransaction(CosignatureTransaction.create(aggregateTransaction))
);
console.log('Cosignatory 3 signed and announced.')
}
});
});
// first announce the lockfunds
network.announceAndWaitForConfirmation(signedHashLock).then(_ => {
// now announce the modify msig
network.announceAndWaitForConfirmation(signedAggregateBonded, true). then(_ => {
// will be confirmed only after all soon-to-be cosigners confirm the transaction (opt-in)
console.log('Converted to multisig.');
});
});
});
});
});
})