11import { VmType } from "@reservoir0x/relay-protocol-sdk" ;
22import { PublicKey } from "@solana/web3.js" ;
3+ import { bech32 , bech32m } from "bech32" ;
4+ import bs58 from "bs58" ;
35
46import { externalError } from "../common/error" ;
57
@@ -57,6 +59,46 @@ export const nvAddress = (address: string, vmType: VmType) => {
5759 }
5860 }
5961
62+ case "bitcoin-vm" : {
63+ try {
64+ // For bech32 addresses (P2WPKH)
65+ try {
66+ const decoded = bech32 . decode ( address ) ;
67+ // Validate that it's a Bitcoin address by checking the prefix
68+ if ( decoded . prefix !== "bc" && decoded . prefix !== "tb" ) {
69+ throw new Error ( "Invalid Bitcoin address prefix" ) ;
70+ }
71+ return address ;
72+ } catch ( e1 ) {
73+ // For bech32m addresses (P2TR)
74+ try {
75+ const decoded = bech32m . decode ( address ) ;
76+ // Validate that it's a Bitcoin address by checking the prefix
77+ if ( decoded . prefix !== "bc" && decoded . prefix !== "tb" ) {
78+ throw new Error ( "Invalid Bitcoin address prefix" ) ;
79+ }
80+ return address ;
81+ } catch ( e2 ) {
82+ // For P2PKH / P2SH (base58 encoded)
83+ bs58 . decode ( address ) ;
84+
85+ // Validate address format
86+ // P2PKH starts with 1, P2SH starts with 3
87+ if ( address . startsWith ( "1" ) || address . startsWith ( "3" ) ) {
88+ // Additional validation: check length
89+ if ( address . length < 26 || address . length > 35 ) {
90+ throw new Error ( "Invalid Bitcoin address length" ) ;
91+ }
92+ return address ;
93+ }
94+ throw new Error ( "Invalid Bitcoin address format" ) ;
95+ }
96+ }
97+ } catch ( e ) {
98+ throw externalError ( `Invalid address: ${ address } ` ) ;
99+ }
100+ }
101+
60102 default : {
61103 throw externalError ( "Vm type not implemented" ) ;
62104 }
@@ -66,6 +108,8 @@ export const nvAddress = (address: string, vmType: VmType) => {
66108// Normalize and validate a currency
67109export const nvCurrency = ( currency : string , vmType : VmType ) => {
68110 switch ( vmType ) {
111+
112+ case "bitcoin-vm" :
69113 case "ethereum-vm" : {
70114 const requiredLengthInBytes = 20 ;
71115
@@ -131,6 +175,17 @@ export const nvTransactionId = (transactionId: string, vmType: VmType) => {
131175 return transactionId ;
132176 }
133177
178+ case "bitcoin-vm" : {
179+ const requiredLengthInBytes = 32 ;
180+
181+ const hexString = nvBytes ( transactionId , requiredLengthInBytes ) ;
182+ if ( hexString . length !== 2 + requiredLengthInBytes * 2 ) {
183+ throw externalError ( `Invalid transaction id: ${ transactionId } ` ) ;
184+ }
185+
186+ return hexString ;
187+ }
188+
134189 default : {
135190 throw externalError ( "Vm type not implemented" ) ;
136191 }
0 commit comments