-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from ckb-cell/feat/op-return-output
feat(rgbpp-btc): OP_RETURN output support
- Loading branch information
Showing
13 changed files
with
314 additions
and
63 deletions.
There are no files selected for viewing
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,5 @@ | ||
--- | ||
"@rgbpp-sdk/btc": patch | ||
--- | ||
|
||
Support creating OP_RETURN outputs in the sendBtc() API |
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,5 @@ | ||
--- | ||
"@rgbpp-sdk/btc": patch | ||
--- | ||
|
||
Fix the error message reading from the BtcAssetsApi response |
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
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
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
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,72 @@ | ||
import bitcoin from 'bitcoinjs-lib'; | ||
import { ErrorCodes, TxBuildError } from '../error'; | ||
|
||
/** | ||
* Convert data to OP_RETURN script pubkey. | ||
* The data size should be ranged in 1 to 80 bytes. | ||
* | ||
* @example | ||
* const data = Buffer.from('01020304', 'hex'); | ||
* const scriptPk = dataToOpReturnScriptPubkey(data); // <Buffer 6a 04 01 02 03 04> | ||
* const scriptPkHex = scriptPk.toString('hex'); // 6a0401020304 | ||
*/ | ||
export function dataToOpReturnScriptPubkey(data: Buffer): Buffer { | ||
const payment = bitcoin.payments.embed({ data: [data] }); | ||
return payment.output!; | ||
} | ||
|
||
/** | ||
* Get data from a OP_RETURN script pubkey. | ||
* | ||
* @example | ||
* const scriptPk = Buffer.from('6a0401020304', 'hex'); | ||
* const data = opReturnScriptPubKeyToData(scriptPk); // <Buffer 01 02 03 04> | ||
* const hex = data.toString('hex'); // 01020304 | ||
*/ | ||
export function opReturnScriptPubKeyToData(script: Buffer): Buffer { | ||
if (!isOpReturnScriptPubkey(script)) { | ||
throw new TxBuildError(ErrorCodes.INVALID_OP_RETURN_SCRIPT); | ||
} | ||
|
||
const [_op, data] = bitcoin.script.decompile(script)!; | ||
return data as Buffer; | ||
} | ||
|
||
/** | ||
* Check if a script pubkey is an OP_RETURN script. | ||
* | ||
* A valid OP_RETURN script should have the following structure: | ||
* - <OP_RETURN code> <size: n> <data of n bytes> | ||
* - <OP_RETURN code> <OP_PUSHDATA1> <size: n> <data of n bytes> | ||
* | ||
* @example | ||
* // <OP_RETURN> <size: 0x04> <data: 01020304> | ||
* isOpReturnScriptPubkey(Buffer.from('6a0401020304', 'hex')); // true | ||
* // <OP_RETURN> <OP_PUSHDATA1> <size: 0x0f> <data: 746573742d636f6d6d69746d656e74> | ||
* isOpReturnScriptPubkey(Buffer.from('6a4c0f746573742d636f6d6d69746d656e74', 'hex')); // true | ||
* // <OP_RETURN> <OP_PUSHDATA1> | ||
* isOpReturnScriptPubkey(Buffer.from('6a4c', 'hex')); // false | ||
* // <OP_RETURN> <size: 0x01> | ||
* isOpReturnScriptPubkey(Buffer.from('6a01', 'hex')); // false | ||
* // <OP_DUP> ... (not an OP_RETURN script) | ||
* isOpReturnScriptPubkey(Buffer.from('76a914a802fc56c704ce87c42d7c92eb75e7896bdc41e788ac', 'hex')); // false | ||
*/ | ||
export function isOpReturnScriptPubkey(script: Buffer): boolean { | ||
const scripts = bitcoin.script.decompile(script); | ||
if (!scripts || scripts.length !== 2) { | ||
return false; | ||
} | ||
|
||
const [op, data] = scripts!; | ||
// OP_RETURN opcode is 0x6a in hex or 106 in integer | ||
if (op !== bitcoin.opcodes.OP_RETURN) { | ||
return false; | ||
} | ||
// Standard OP_RETURN data size is up to 80 bytes | ||
if (!(data instanceof Buffer) || data.byteLength < 1 || data.byteLength > 80) { | ||
return false; | ||
} | ||
|
||
// No false condition matched, it's an OP_RETURN script | ||
return true; | ||
} |
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,40 @@ | ||
import { describe, it, expect } from 'vitest'; | ||
import { dataToOpReturnScriptPubkey, opReturnScriptPubKeyToData } from '../src/transaction/embed'; | ||
|
||
describe('Embed', () => { | ||
it('Encode UTF-8 data to OP_RETURN script pubkey', () => { | ||
const data = Buffer.from('test-commitment', 'utf-8'); | ||
const script = dataToOpReturnScriptPubkey(data); | ||
|
||
expect(script.toString('hex')).toEqual('6a0f746573742d636f6d6d69746d656e74'); | ||
}); | ||
it('Decode UTF-8 data from OP_RETURN script pubkey', () => { | ||
const script = Buffer.from('6a0f746573742d636f6d6d69746d656e74', 'hex'); | ||
const data = opReturnScriptPubKeyToData(script); | ||
|
||
expect(data.toString('utf-8')).toEqual('test-commitment'); | ||
}); | ||
|
||
it('Decode 32-byte hex from OP_RETURN script pubkey', () => { | ||
const hex = '00'.repeat(32); | ||
const script = Buffer.from('6a20' + hex, 'hex'); | ||
const data = opReturnScriptPubKeyToData(script); | ||
|
||
expect(data.toString('hex')).toEqual(hex); | ||
}); | ||
|
||
it('Encode 80-byte data to OP_RETURN script pubkey', () => { | ||
const hex = '00'.repeat(80); | ||
const data = Buffer.from(hex, 'hex'); | ||
const script = dataToOpReturnScriptPubkey(data); | ||
|
||
expect(script.toString('hex')).toEqual('6a4c50' + hex); | ||
}); | ||
it('Decode 80-byte hex from OP_RETURN script pubkey', () => { | ||
const hex = '00'.repeat(80); | ||
const script = Buffer.from('6a4c50' + hex, 'hex'); | ||
const data = opReturnScriptPubKeyToData(script); | ||
|
||
expect(data.toString('hex')).toEqual(hex); | ||
}); | ||
}); |
Oops, something went wrong.
09de175
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.