Here is an end to end example of creating and executing a multisig with Polkadot JS: ```javascript const { ApiPromise, WsProvider } = require('@polkadot/api'); const { Keyring } = require('@polkadot/keyring'); const { cryptoWaitReady, createKeyMulti, encodeAddress, sortAddresses, } = require('@polkadot/util-crypto'); const SS58Prefix = 2; async function multisigTransfer() { await cryptoWaitReady(); // create a keyring with some non-default values specified const keyring = new Keyring({ type: 'sr25519', ss58Format: SS58Prefix }); // Connect to the local Polkadot node const wsProvider = new WsProvider('ws://localhost:9944'); const api = await ApiPromise.create({ provider: wsProvider }); // Retrieve the chain & node information via rpc calls const [chain, nodeName, nodeVersion] = await Promise.all([ api.rpc.system.chain(), api.rpc.system.name(), api.rpc.system.version() ]); console.log(`You are connected to chain ${chain} using ${nodeName} v${nodeVersion}`); // create accounts based on the development seed const alice = keyring.addFromUri('//Alice'); const bob = keyring.addFromUri('//Bob'); const charlie = keyring.addFromUri('//Charlie'); // Define the multisig transfer details const multisigCall = api.tx.balances.transfer(alice.address, 1_234_567); const addresses = [alice.address, bob.address, charlie.address] const threshold = 2; const { weight: maxWeight } = await multisigCall.paymentInfo(alice); // Address as a byte array. const multisigAddress = encodeAddress(createKeyMulti(addresses, threshold), SS58Prefix); console.log(multisigAddress); await fundAddress(api, alice, multisigAddress, 1_000_000_000_000) await approveMultisigWithHash(api, alice, threshold, addresses, null, multisigCall.method.hash, maxWeight); const info = await api.query.multisig.multisigs(multisigAddress, multisigCall.method.hash); const timepoint = info.unwrap().when; await approveMultisigWithHash(api, bob, threshold, addresses, timepoint, multisigCall.method.hash, maxWeight); await finalizeMultisig(api, charlie, threshold, addresses, timepoint, multisigCall, maxWeight); } async function fundAddress(api, sender, to, amount) { return new Promise((resolve, reject) => { api.tx.balances .transfer(to, amount) .signAndSend(sender, async (result) => { console.log(`Current status is ${result.status}`); if (result.status.isInBlock) { console.log(`Transfer completed at blockHash ${result.status.asInBlock}`); resolve(); } }).catch((error) => { reject(error); }); }); } async function approveMultisigWithHash(api, sender, threshold, addresses, timepoint, callHash, maxWeight) { return new Promise((resolve, reject) => { // Take addresses and remove the sender. const otherSignatories = addresses.filter((who) => who !== sender.address); // Sort them by public key. const otherSignatoriesSorted = sortAddresses(otherSignatories, SS58Prefix); api.tx.multisig .approveAsMulti(threshold, otherSignatoriesSorted, timepoint, callHash, maxWeight) .signAndSend(sender, async (result) => { console.log(`Current status is ${result.status}`); if (result.status.isInBlock) { console.log(`Transaction included at blockHash ${result.status.asInBlock}`); resolve(); } }).catch((error) => { reject(error); }); }); } async function finalizeMultisig(api, sender, threshold, addresses, timepoint, multisigCall, maxWeight) { return new Promise((resolve, reject) => { // Take addresses and remove the sender. const otherSignatories = addresses.filter((who) => who !== sender.address); // Sort them by public key. const otherSignatoriesSorted = sortAddresses(otherSignatories, SS58Prefix); api.tx.multisig .asMulti(threshold, otherSignatoriesSorted, timepoint, multisigCall, maxWeight) .signAndSend(sender, async (result) => { console.log(`Current status is ${result.status}`); if (result.status.isInBlock) { console.log(`Transaction included at blockHash ${result.status.asInBlock}`); resolve(); } }).catch((error) => { reject(error); }); }); } multisigTransfer().catch(console.error); ``` Here you can see all the events emitted, showing the end to end scenario works on a local polkadot dev envrionment: [![enter image description here][1]][1] Here was a resource I found which helped me complete the scenario: https://github.com/polkadot-js/api/issues/2878 [1]: https://i.sstatic.net/4TsKHaLj.png