diff --git a/content/documentation/recipes_multisig_sign_transaction.mdx b/content/documentation/recipes_multisig_sign_transaction.mdx index 85b60775..fac4efd9 100644 --- a/content/documentation/recipes_multisig_sign_transaction.mdx +++ b/content/documentation/recipes_multisig_sign_transaction.mdx @@ -6,21 +6,74 @@ description: Recipes | Multisig | Signing Transactions with Multisig Accounts | **Learn how to create multisignature accounts [here](./recipes_multisig_create_account).** Once you have created the multisignature accounts, signing a transaction involves the following steps: -1. Create the signing commitment (performed by each participant) -2. Aggregate the signing commitments to create the signing package (performed by a coordinator) -3. Create signature shares using the signing package (performed by each participant) -4. Aggregate the signature shares to create the final signed transaction (performed by a coordinator) +1. Create an unsigned transaction for participants to sign +2. Create the signing commitment (performed by each participant) +3. Aggregate the signing commitments to create the signing package (performed by a coordinator) +4. Create signature shares using the signing package (performed by each participant) +5. Aggregate the signature shares to create the final signed transaction (performed by a coordinator) In the examples below, we will be signing a transaction with 2 of 2 multisig accounts. +## Create the unsigned transaction + +Any account in the multisig group (or a view-only account that possesses the group view keys) can initiate sending a transaction by generating an "unsigned transaction". A raw transaction contains the parameters of a transaction, like which notes will be spent, which notes will be created, and who will own the notes. An unsigned transaction contains pre-computed zero-knowledge proofs in its spend, output, mint, and burn descriptions, but lacks the authorizing signature required for valid spends and mints. + +The example below shows how to create a raw transaction to send 10 $ORE to two addresses and then generate an unsigned transaction from that raw transaction: + +```js +import { BuildTransactionRequest, CreateTransactionRequest, CurrencyUtils, IronfishSdk } from '@ironfish/sdk' +import { Asset } from '@ironfish/rust-nodejs' + +async function main(): Promise { + const sdk = await IronfishSdk.init({ dataDir: '~/.dev0' }); + const client = await sdk.connectRpc(); + + const accountName = 'MyMultisigAccount'; + + // Create the raw transaction + const createOptions: CreateTransactionRequest = { + account: accountName, + outputs: [ + { + publicAddress: 'b28b5d5a629b57f15e73ee6040efe9a8a0abca54a439e9ef5a8686b5765684ee', + amount: CurrencyUtils.encode(10n), + memo: '', + assetId: Asset.nativeId().toString('hex'), + }, + { + publicAddress: '34ba96315e36de52a3138475776f91df215ebbd868757c61a32dfe34563bd51f', + amount: CurrencyUtils.encode(10n), + memo: '', + assetId: Asset.nativeId().toString('hex'), + }, + ], + fee: CurrencyUtils.encode(1n), + // don't expire until 60 blocks from the current chain head to allow enough time for signing + expirationDelta: 60, + }; + + const createResponse = await client.wallet.createTransaction(createOptions); + const rawTransaction = createResponse.content.transaction; + + // Build the raw transaction to create an unsigned transaction + const buildOptions: BuildTransactionRequest = { + account: accountName, + rawTransaction, + }; + + const buildResponse = await client.wallet.buildTransaction(buildOptions); + console.log(buildResponse.content.unsignedTransaction); +} +``` + +**Tip:** Make sure the unsigned transaction has a sufficient expiration time to allow for the completion of the signing process. The expiration can be set to 0 to ensure the transaction never expires. + ## Create the signing commitment Once the participants agree on the contents of a transaction and who is going to participate in signing, each participant will create a signing commitment. The identities of the participant and the unsigned transaction are required to generate a commitment. -**Tip:** Make sure the unsigned transaction has a sufficient expiration time to allow for the completion of the signing process. The expiration can be set to 0 to ensure the transaction never expires. - ```js import { multisig } from '@ironfish/rust-nodejs'