Skip to content

Commit

Permalink
feat(sdk): add taproot tree version for backward compatibility (#119)
Browse files Browse the repository at this point in the history
* feat(sdk): add taproot tree version for backward compatibility

* add strict typing for taptree version

* lint

* add comments
  • Loading branch information
kevzzsk authored Jun 10, 2024
1 parent 2d8de57 commit c5b54f8
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 8 deletions.
3 changes: 2 additions & 1 deletion packages/sdk/src/inscription/collection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BaseDatasource, GetWalletOptions, Inscriber, JsonRpcDatasource, verifyMessage } from ".."
import { BaseDatasource, GetWalletOptions, Inscriber, JsonRpcDatasource, TaptreeVersion, verifyMessage } from ".."
import { Network } from "../config/types"
import { MAXIMUM_ROYALTY_PERCENTAGE } from "../constants"
import { OrditSDKError } from "../utils/errors"
Expand Down Expand Up @@ -171,6 +171,7 @@ export type MintFromCollectionOptions = Pick<GetWalletOptions, "safeMode"> & {
datasource?: BaseDatasource
// temporary flag for backward compatibility
includeMintAddress?: boolean
taptreeVersion?: TaptreeVersion
}

type Outputs = Array<{ address: string; value: number }>
54 changes: 48 additions & 6 deletions packages/sdk/src/transactions/Inscriber.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as ecc from "@bitcoinerlab/secp256k1"
import * as bitcoin from "bitcoinjs-lib"
import { Tapleaf } from "bitcoinjs-lib/src/types"
import { Taptree } from "bitcoinjs-lib/src/types"

import {
BaseDatasource,
Expand All @@ -10,7 +10,8 @@ import {
getDummyP2TRInput,
getNetwork,
GetWalletOptions,
OnOffUnion
OnOffUnion,
TaptreeVersion
} from ".."
import { Network } from "../config/types"
import { MINIMUM_AMOUNT_IN_SATS } from "../constants"
Expand All @@ -25,6 +26,7 @@ export class Inscriber extends PSBTBuilder {
protected mediaType: string
protected mediaContent: string
protected meta?: NestedObject
protected taptreeVersion?: TaptreeVersion = "1"
protected postage: number

private ready = false
Expand All @@ -38,11 +40,12 @@ export class Inscriber extends PSBTBuilder {
private encodeMetadata: boolean
private previewMode = false

private witnessScripts: Record<"inscription" | "recovery", Buffer | null> = {
private witnessScripts: Record<"inscription" | "recovery" | "inscriptionOnly", Buffer | null> = {
inscription: null,
inscriptionOnly: null,
recovery: null
}
private taprootTree!: [Tapleaf, Tapleaf]
private taprootTree!: Taptree

constructor({
network,
Expand All @@ -58,6 +61,7 @@ export class Inscriber extends PSBTBuilder {
encodeMetadata = false,
safeMode,
meta,
taptreeVersion,
datasource
}: InscriberArgOptions) {
super({
Expand All @@ -78,6 +82,7 @@ export class Inscriber extends PSBTBuilder {
this.mediaType = mediaType
this.mediaContent = mediaContent
this.meta = meta
this.taptreeVersion = taptreeVersion
this.postage = postage
this.safeMode = !safeMode ? "on" : safeMode
this.encodeMetadata = encodeMetadata
Expand Down Expand Up @@ -161,6 +166,12 @@ export class Inscriber extends PSBTBuilder {
meta: this.getMetadata(),
xkey: this.xKey
}),
inscriptionOnly: buildWitnessScript({
mediaContent: this.mediaContent,
mediaType: this.mediaType,
meta: false, // do not pass in metadata for v2
xkey: this.xKey
}),
recovery: buildWitnessScript({
mediaContent: this.mediaContent,
mediaType: this.mediaType,
Expand All @@ -173,7 +184,30 @@ export class Inscriber extends PSBTBuilder {

buildTaprootTree() {
this.buildWitness()
this.taprootTree = [{ output: this.witnessScripts.inscription! }, { output: this.witnessScripts.recovery! }]
switch (this.taptreeVersion) {
case "2":
// v2 allows for inscription only minting (without meta) and remains unique based on the meta (OIP-2 specs)
this.taprootTree = [
[{ output: this.witnessScripts.recovery! }, { output: this.witnessScripts.inscription! }],
{ output: this.witnessScripts.inscriptionOnly! }
]
break
case "1":
default:
// v1 allows for inscription (with meta) and recovery minting (OIP-2 specs)
this.taprootTree = [{ output: this.witnessScripts.inscription! }, { output: this.witnessScripts.recovery! }]
break
}
}

getReedemScript(): bitcoin.payments.Payment["redeem"] {
switch (this.taptreeVersion) {
case "2":
return this.getInscriptionOnlyRedeemScript()
case "1":
default:
return this.getInscriptionRedeemScript()
}
}

getInscriptionRedeemScript(): bitcoin.payments.Payment["redeem"] {
Expand All @@ -183,6 +217,13 @@ export class Inscriber extends PSBTBuilder {
}
}

getInscriptionOnlyRedeemScript(): bitcoin.payments.Payment["redeem"] {
return {
output: this.witnessScripts.inscriptionOnly!,
redeemVersion: 192
}
}

getRecoveryRedeemScript(): bitcoin.payments.Payment["redeem"] {
return {
output: this.witnessScripts.recovery!,
Expand Down Expand Up @@ -230,7 +271,7 @@ export class Inscriber extends PSBTBuilder {
internalPubkey: Buffer.from(this.xKey, "hex"),
network: getNetwork(this.network),
scriptTree: this.taprootTree,
redeem: this.getInscriptionRedeemScript()
redeem: this.getReedemScript()
})
this.witness = this.payment.witness

Expand Down Expand Up @@ -315,6 +356,7 @@ export type InscriberArgOptions = Pick<GetWalletOptions, "safeMode"> & {
mediaContent: string
changeAddress: string
meta?: NestedObject
taptreeVersion?: TaptreeVersion
outputs?: Outputs
encodeMetadata?: boolean
datasource?: BaseDatasource
Expand Down
4 changes: 3 additions & 1 deletion packages/sdk/src/transactions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export type Transaction = {
}

// used in Address.GetTransactions RPC, needed due to response not matching Transaction type (ex. blockhash vs blockHash)
export type TransactionV2 = Omit<Transaction, 'blockhash' | 'blockheight' | 'blocktime'> & {
export type TransactionV2 = Omit<Transaction, "blockhash" | "blockheight" | "blocktime"> & {
blockHash: string
blockHeight: number
blockTime: number
Expand Down Expand Up @@ -95,3 +95,5 @@ export interface SkipStrictSatsCheckOptions {
skipStrictSatsCheck?: boolean
customAmount?: number
}

export type TaptreeVersion = "1" | "2"

0 comments on commit c5b54f8

Please sign in to comment.