-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(utils): add the serializeScript method in the utils module
- Loading branch information
Showing
4 changed files
with
186 additions
and
0 deletions.
There are no files selected for viewing
68 changes: 68 additions & 0 deletions
68
packages/ckb-sdk-utils/__tests__/serialization/fixtures.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
{ | ||
"serializeArg": [ | ||
{ | ||
"arg": "", | ||
"expected": "00000000" | ||
}, | ||
{ | ||
"arg": "0x", | ||
"expected": "00000000" | ||
}, | ||
{ | ||
"arg": "0x00", | ||
"expected": "0100000000" | ||
}, | ||
{ | ||
"arg": "00", | ||
"expected": "0100000000" | ||
}, | ||
{ | ||
"arg": "0x1010101010101010101010", | ||
"expected": "0b0000001010101010101010101010" | ||
} | ||
], | ||
"serializeArgs": [ | ||
{ | ||
"args": [], | ||
"expected": "04000000" | ||
}, | ||
{ | ||
"args": ["0x10", "0x01"], | ||
"expected": "160000000c0000001100000001000000100100000001" | ||
}, | ||
{ | ||
"args": ["0x3954acece65096bfa81258983ddb83915fc56bd8"], | ||
"expected": "2000000008000000140000003954acece65096bfa81258983ddb83915fc56bd8" | ||
} | ||
], | ||
"serializeCodeHash": [ | ||
{ | ||
"codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", | ||
"expected": "68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88" | ||
}, | ||
{ | ||
"codeHash": "68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", | ||
"expected": "68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88" | ||
} | ||
], | ||
"serializeHashType": [ | ||
{ | ||
"hashType": "data", | ||
"expected": "00" | ||
}, | ||
{ | ||
"hashType": "type", | ||
"expected": "01" | ||
} | ||
], | ||
"serializeScript": [ | ||
{ | ||
"script": { | ||
"codeHash": "0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", | ||
"args": ["0x3954acece65096bfa81258983ddb83915fc56bd8"], | ||
"hashType": "type" | ||
}, | ||
"expected": "5100000010000000300000003100000068d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88012000000008000000140000003954acece65096bfa81258983ddb83915fc56bd8" | ||
} | ||
] | ||
} |
40 changes: 40 additions & 0 deletions
40
packages/ckb-sdk-utils/__tests__/serialization/index.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
const ckbUtils = require('../../lib') | ||
const fixtures = require('./fixtures.json') | ||
|
||
const { serializeHash, serializeArg, serializeArgs, serializeCodeHash, serializeHashType, serializeScript } = ckbUtils | ||
|
||
describe('Serialize Arg and Hash', () => { | ||
const fixtureTable = fixtures.serializeArg.map(({ arg, expected }) => [arg, expected]) | ||
test.each(fixtureTable)('%j => %s', (arg, expected) => { | ||
expect(serializeArg(arg)).toBe(expected) | ||
expect(serializeHash(arg)).toBe(expected) | ||
}) | ||
}) | ||
|
||
describe('Serialize Args', () => { | ||
const fixtureTable = fixtures.serializeArgs.map(({ args, expected }) => [args, expected]) | ||
test.each(fixtureTable)('%j => %s', (args, expected) => { | ||
expect(serializeArgs(args)).toBe(expected) | ||
}) | ||
}) | ||
|
||
describe('Serialize CodeHash', () => { | ||
const fixtureTable = fixtures.serializeCodeHash.map(({ codeHash, expected }) => [codeHash, expected]) | ||
test.each(fixtureTable)('%s => %s', (codeHash, expected) => { | ||
expect(serializeCodeHash(codeHash)).toBe(expected) | ||
}) | ||
}) | ||
|
||
describe('Serialize HashType', () => { | ||
const fixtureTable = fixtures.serializeHashType.map(({ hashType, expected }) => [hashType, expected]) | ||
test.each(fixtureTable)('%s => %s', (hashType, expected) => { | ||
expect(serializeHashType(hashType)).toBe(expected) | ||
}) | ||
}) | ||
|
||
describe('Serialize Script', () => { | ||
const fixtureTable = fixtures.serializeScript.map(({ script, expected }) => [script, expected]) | ||
test.each(fixtureTable)('%j => %s', (script, expected) => { | ||
expect(serializeScript(script)).toBe(expected) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { hexToBytes, bytesToHex, toHexInLittleEndian } from '..' | ||
|
||
const offsetSize = 4 // 4 bytes | ||
const fullLengthSize = 4 // 4 bytes | ||
|
||
const getOffsets = (elmLengths: number[]) => { | ||
const headerLength = fullLengthSize + offsetSize * elmLengths.length | ||
const offsets = [headerLength] | ||
elmLengths.forEach((_, idx: number) => { | ||
if (idx) { | ||
offsets.push(offsets[offsets.length - 1] + elmLengths[idx - 1]) | ||
} | ||
}) | ||
return offsets | ||
} | ||
|
||
export const serializeHash = (arg: CKBComponents.Hash) => { | ||
const bytes = hexToBytes(arg) | ||
const header = toHexInLittleEndian(bytes.length) | ||
const body = bytesToHex(bytes) | ||
return `${header}${body}` | ||
} | ||
|
||
export const serializeCodeHash = (codeHash: CKBComponents.Hash256) => { | ||
const bytes = hexToBytes(codeHash) | ||
const body = bytesToHex(bytes) | ||
return body | ||
} | ||
|
||
export const serializeArg = (arg: CKBComponents.Hash) => serializeHash(arg) | ||
|
||
export const serializeHashType = (hashType: CKBComponents.ScriptHashType) => { | ||
if (hashType === 'data') return '00' | ||
if (hashType === 'type') return '01' | ||
throw new TypeError("Hash type must by either of 'data' or 'type'") | ||
} | ||
|
||
export const serializeArgs = (args: string[]) => { | ||
if (!args.length) return '04000000' | ||
const serializedArgs = args.map(serializeArg) | ||
const headerLength = fullLengthSize + offsetSize * serializedArgs.length | ||
const fullLength = toHexInLittleEndian(headerLength + serializedArgs.join('').length / 2) | ||
const offsets = getOffsets(serializedArgs.map(arg => arg.length / 2)).map(offset => toHexInLittleEndian(offset)) | ||
return [fullLength, ...offsets, ...serializedArgs].join('') | ||
} | ||
|
||
export const serializeScript = (script: CKBComponents.Script) => { | ||
if (!script) throw new Error('Script is required') | ||
const { codeHash = '', hashType, args = [] } = script | ||
const serializedCodeHash = serializeCodeHash(codeHash) | ||
const serializedHashType = serializeHashType(hashType) | ||
const serializedArgs = serializeArgs(args) | ||
const elms = [serializedCodeHash, serializedHashType, serializedArgs] | ||
const fullLength = toHexInLittleEndian( | ||
fullLengthSize + | ||
offsetSize * 3 + | ||
(serializedCodeHash.length + serializedHashType.length + serializedArgs.length) / 2 | ||
) | ||
|
||
const offsets = getOffsets(elms.map(elm => elm.length / 2)).map(offset => toHexInLittleEndian(offset)) | ||
return [fullLength, ...offsets, ...elms].join('') | ||
} | ||
|
||
export default { | ||
serializeHash, | ||
serializeCodeHash, | ||
serializeArg, | ||
serializeArgs, | ||
serializeHashType, | ||
serializeScript, | ||
} |