Skip to content

Commit

Permalink
👌 IMPROVE: Sign transactions api now supports metaid edit to update t…
Browse files Browse the repository at this point in the history
…he sequentially dependent infos in op_return
  • Loading branch information
riverrun46 committed Sep 25, 2023
1 parent e2a8a96 commit b2967f0
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/lib/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BN, mvc } from 'meta-contract'
import { Buffer } from 'buffer'
import { getMvcRootPath, type Account } from './account'
import { parseLocalTransaction } from './metadata'

export function eciesEncrypt(message: string, privateKey: mvc.PrivateKey): string {
const publicKey = privateKey.toPublicKey()
Expand Down Expand Up @@ -74,6 +75,7 @@ type ToSignTransaction = {
satoshis: number
sigtype?: number
path?: string
hasMetaId?: boolean
}
export const signTransaction = async (
account: Account,
Expand Down Expand Up @@ -158,7 +160,7 @@ export const signTransactions = async (
txid: string
}[] = []
for (let i = 0; i < toSignTransactionsWithDependsOn.length; i++) {
let { txHex, scriptHex, inputIndex, satoshis, sigtype } = toSignTransactionsWithDependsOn[i]
let { txHex, scriptHex, inputIndex, satoshis, sigtype, hasMetaId } = toSignTransactionsWithDependsOn[i]
const toSign = toSignTransactionsWithDependsOn[i]

if (!sigtype) {
Expand All @@ -170,8 +172,35 @@ export const signTransactions = async (
// find out if this transaction depends on previous ones
// if so, we need to update the prevTxId of the current one
if (toSign.dependsOn !== undefined) {
const wrongTxId = tx.inputs[inputIndex].prevTxId.toString('hex')

const prevTxId = signedTransactions[toSign.dependsOn].txid
tx.inputs[inputIndex].prevTxId = Buffer.from(prevTxId, 'hex')

// if hasMetaId is true, we need to also update the parent txid written in OP_RETURN
if (hasMetaId) {
const { messages: metaIdMessages, outputIndex } = await parseLocalTransaction(tx)

if (outputIndex !== null) {
// find out if prevTxId is already in the messages;
// if so, we need to replace it with the new one
for (let i = 0; i < metaIdMessages.length; i++) {
if (metaIdMessages[i].includes(wrongTxId)) {
metaIdMessages[i] = metaIdMessages[i].replace(wrongTxId, prevTxId)
break
}
}

// update the OP_RETURN
const opReturnOutput = new mvc.Transaction.Output({
script: mvc.Script.buildSafeDataOut(metaIdMessages),
satoshis: 0,
})

// update the OP_RETURN output in tx
tx.outputs[outputIndex] = opReturnOutput
}
}
}

// find out priv / pub according to path
Expand Down
23 changes: 23 additions & 0 deletions src/lib/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,27 @@ export async function parse(txid: string, outputIndex: number): Promise<string[]
return messages
}

export async function parseLocalTransaction(transaction: mvc.Transaction) {
// loop through all outputs and find the one with OP_RETURN
const outputs = transaction.outputs
const outputIndex = outputs.findIndex((output) => output.script.toASM().includes('OP_RETURN'))

if (outputIndex === -1)
return {
messages: [],
outputIndex: null,
}

const outputAsm = outputs[outputIndex].script.toASM()
const asmFractions = outputAsm.split('OP_RETURN')[1].trim().split(' ')
let messages = asmFractions.map((fraction: string) => {
return Buffer.from(fraction, 'hex').toString()
})

return {
messages,
outputIndex,
}
}

export default parseMetaData

0 comments on commit b2967f0

Please sign in to comment.