Skip to content

Commit

Permalink
feat: compatible ckb-cli tx multisig file (#3169)
Browse files Browse the repository at this point in the history
  • Loading branch information
devchenyan authored Jun 7, 2024
1 parent ee2fa9b commit 77d99fb
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 7 deletions.
4 changes: 2 additions & 2 deletions packages/neuron-ui/src/utils/calculateFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ export const calculateFee = (tx: any) => {
return '0'
}
const inputCapacities = tx.inputs.reduce(
(result: bigint, input: { capacity: string }) => result + BigInt(input.capacity),
(result: bigint, input: { capacity: string }) => result + BigInt(input.capacity || '0'),
BigInt(0)
)
const outputCapacities = tx.outputs.reduce(
(result: bigint, output: { capacity: string }) => result + BigInt(output.capacity),
(result: bigint, output: { capacity: string }) => result + BigInt(output.capacity || '0'),
BigInt(0)
)

Expand Down
10 changes: 8 additions & 2 deletions packages/neuron-wallet/src/controllers/multisig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { t } from 'i18next'
import { computeScriptHash as scriptToHash } from '@ckb-lumos/base/lib/utils'
import { scriptToAddress, addressToScript } from '../utils/scriptAndAddress'
import { ResponseCode } from '../utils/const'
import { parseMultisigTxJsonFromCkbCli } from '../utils/multisig'
import MultisigConfig from '../database/chain/entities/multisig-config'
import MultisigConfigModel from '../models/multisig-config'
import MultisigService from '../services/multisig'
Expand Down Expand Up @@ -246,7 +247,12 @@ export default class MultisigController {
}
const tx = result.json
const lockHash = scriptToHash(addressToScript(fullPayload))
if (tx.transaction.inputs.every(v => v.lockHash !== lockHash)) {

if (tx.transaction) {
tx.transaction = parseMultisigTxJsonFromCkbCli(tx)
}

if (tx.transaction.inputs.every(v => v.lockHash && v.lockHash !== lockHash)) {
ShowGlobalDialogSubject.next({
type: 'failed',
title: t('common.error'),
Expand All @@ -258,7 +264,7 @@ export default class MultisigController {
}
return {
status: ResponseCode.Success,
result: result?.json,
result: tx,
}
}
}
5 changes: 3 additions & 2 deletions packages/neuron-wallet/src/models/chain/cell-dep.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import OutPoint from './out-point'
import { snakeToCamel } from '../../utils/deep-camelize-keys'

export enum DepType {
Code = 'code',
Expand All @@ -14,8 +15,8 @@ export default class CellDep {
this.depType = depType
}

public static fromObject({ outPoint, depType }: { outPoint: OutPoint; depType: DepType }): CellDep {
return new CellDep(OutPoint.fromObject(outPoint), depType)
public static fromObject({ outPoint, depType }: { outPoint: OutPoint; depType: DepType | 'dep_group' }): CellDep {
return new CellDep(OutPoint.fromObject(outPoint), snakeToCamel(depType) as DepType)
}

public toSDK(): CKBComponents.CellDep {
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-wallet/src/models/chain/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export default class Transaction {
this.description = description
this.nervosDao = nervosDao
this.assetAccountType = assetAccountType
this.version = BigInt(version).toString()
this.version = BigInt(version || '0x0').toString()
this.value = value ? BigInt(value).toString() : value
this.fee = fee ? BigInt(fee).toString() : fee
this.interest = interest ? BigInt(interest).toString() : interest
Expand Down
1 change: 1 addition & 0 deletions packages/neuron-wallet/src/models/offline-sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface OfflineSignJSON {
description?: string
asset_account?: AssetAccount
multisig_configs?: MultisigConfigs
signatures?: Signatures
}

export default class OfflineSign implements OfflineSignProps {
Expand Down
20 changes: 20 additions & 0 deletions packages/neuron-wallet/src/utils/deep-camelize-keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const snakeToCamel = (str: string): string => {
if (!str) return ''
return str.replace(/([-_][a-z])/gi, c => c.toUpperCase().replace(/[-_]/g, ''))
}

export const deepCamelizeKeys = (item: unknown): unknown => {
if (Array.isArray(item)) {
return item.map((el: unknown) => deepCamelizeKeys(el))
} else if (typeof item === 'function' || item !== Object(item)) {
return item
}
return Object.fromEntries(
Object.entries(item as Record<string, unknown>).map(([key, value]: [string, unknown]) => [
key.replace(/([-_][a-z])/gi, c => c.toUpperCase().replace(/[-_]/g, '')),
deepCamelizeKeys(value),
])
)
}

export default { deepCamelizeKeys, snakeToCamel }
25 changes: 25 additions & 0 deletions packages/neuron-wallet/src/utils/multisig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { computeScriptHash as scriptToHash } from '@ckb-lumos/base/lib/utils'
import Multisig from '../models/multisig'
import MultisigConfigModel from '../models/multisig-config'
import { Signatures, SignStatus } from '../models/offline-sign'
import { OfflineSignJSON } from 'src/models/offline-sign'
import Transaction from '../models/chain/transaction'
import SystemScriptInfo from '../models/system-script-info'
import Input from '../models/chain/input'
import { deepCamelizeKeys } from './deep-camelize-keys'

export const getMultisigStatus = (multisigConfig: MultisigConfigModel, signatures: Signatures) => {
const multisigLockHash = scriptToHash(
Expand All @@ -27,6 +32,26 @@ export const getMultisigStatus = (multisigConfig: MultisigConfigModel, signature
return SignStatus.Signed
}

export const parseMultisigTxJsonFromCkbCli = (tx: OfflineSignJSON): Transaction => {
const { multisig_configs, transaction } = tx
const txObj = Transaction.fromObject(deepCamelizeKeys(transaction) as any)
if (multisig_configs && Object.keys(multisig_configs).length) {
const args = Object.keys(multisig_configs)[0]
const lock = SystemScriptInfo.generateMultiSignScript(args)

txObj.inputs.forEach((input: Input) => {
if (!input?.lock) {
input.lock = lock
}
})
}
if (!txObj?.signatures && tx?.signatures) {
txObj.signatures = tx.signatures
}
return txObj
}

export default {
getMultisigStatus,
parseMultisigTxJsonFromCkbCli,
}
101 changes: 101 additions & 0 deletions packages/neuron-wallet/tests/utils/deep-camelize-keys/fixtures.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{
"value": {
"version": "0x0",
"cell_deps": [
{
"out_point": {
"tx_hash": "0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37",
"index": "0x1"
},
"dep_type": "dep_group"
}
],
"header_deps": [],
"inputs": [
{
"since": "0x0",
"previous_output": {
"tx_hash": "0x00bc60fd23dd556a9bd139791e4cb95d678550054953793b79c864abcc733eae",
"index": "0x1"
}
},
{
"previous_output": {
"txHash": "0x8b37ded770fe457e1d3969e93722873308aef1e6810757d248f437de4d009d8f",
"index": "0x1"
},
"since": "0x0"
}
],
"outputs": [
{
"capacity": "6600000000",
"lock": {
"args": "0x2d8765d2d0e007aa227e61d9bc1ebd7343360a58",
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
"hash_type": "type"
},
"type": null
},
{
"capacity": "10399999375",
"lock": {
"args": "0x5b34cc4f76644ec6da564c1ace41711ee0f1e071",
"code_hash": "0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8",
"hash_type": "type"
},
"type": null
}
],
"outputs_data": ["0x", "0x"],
"witnesses": []
},
"expected": {
"version": "0x0",
"inputs": [
{
"since": "0x0",
"previousOutput": {
"index": "0x1",
"txHash": "0x00bc60fd23dd556a9bd139791e4cb95d678550054953793b79c864abcc733eae"
}
},
{
"since": "0x0",
"previousOutput": {
"txHash": "0x8b37ded770fe457e1d3969e93722873308aef1e6810757d248f437de4d009d8f",
"index": "0x1"
}
}
],
"outputs": [
{
"capacity": "6600000000",
"lock": {
"args": "0x2d8765d2d0e007aa227e61d9bc1ebd7343360a58",
"codeHash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
"hashType": "type"
},
"type": null
},
{
"capacity": "10399999375",
"lock": {
"args": "0x5b34cc4f76644ec6da564c1ace41711ee0f1e071",
"codeHash": "0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8",
"hashType": "type"
},
"type": null
}
],
"witnesses": [],
"cellDeps": [
{
"outPoint": { "index": "0x1", "txHash": "0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37" },
"depType": "dep_group"
}
],
"headerDeps": [],
"outputsData": ["0x", "0x"]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { deepCamelizeKeys } from '../../../src/utils/deep-camelize-keys'
import fixtures from './fixtures.json'

describe('test json to hump', () => {
it('json to hump', () => {
const result = deepCamelizeKeys(fixtures.value)
expect(fixtures.expected).toEqual(result)
})
})

0 comments on commit 77d99fb

Please sign in to comment.