Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions sdk/src/gateway/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,13 @@ export { OkxWalletAdapter } from './adapters/okx-wallet';
export { ReownWalletAdapter } from './adapters/reown';
export { ExecuteQuoteResult, GatewayApiClient as GatewaySDK } from './client';
export * from './generated-client';
export { GatewayQuoteParams, GetQuoteParams } from './types';
export { formatBtc, parseBtc } from './utils';
export { BitcoinSigner, GatewayQuoteParams, GetQuoteParams } from './types';
export {
formatBtc,
parseBtc,
ScureBitcoinSigner,
supportedChainsMapping,
getChainConfig,
getInnerQuote,
type InnerQuote,
} from './utils';
30 changes: 30 additions & 0 deletions sdk/src/gateway/utils/bitcoin-signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,36 @@ export class ScureBitcoinSigner implements BitcoinSigner {
this.privateKey = new Uint8Array(Buffer.from(cleanPrivateKey, 'hex'));
}

/**
* Create a Bitcoin signer from a WIF-encoded private key
* @param wif WIF-encoded private key string
* @returns A new ScureBitcoinSigner instance
*/
static fromWIF(wif: string): ScureBitcoinSigner {
const decoded = btc.WIF().decode(wif);
return new ScureBitcoinSigner(Buffer.from(decoded).toString('hex'));
}

/**
* Create a Bitcoin signer from a private key in any supported format (hex or WIF).
* Auto-detects the format.
* @param key Private key as hex string (with or without 0x prefix) or WIF-encoded
* @returns A new ScureBitcoinSigner instance
*/
static fromKey(key: string): ScureBitcoinSigner {
const stripped = key.startsWith('0x') ? key.slice(2) : key;
if (/^[0-9a-fA-F]{64}$/.test(stripped)) {
return new ScureBitcoinSigner(stripped);
}
try {
return ScureBitcoinSigner.fromWIF(key);
} catch (e) {
throw new Error('Invalid private key: expected 64-char hex (with optional 0x prefix) or WIF-encoded key', {
cause: e,
});
}
}

/**
* Create a Bitcoin signer from a seed phrase (BIP39 mnemonic)
* @param seedPhrase The BIP39 mnemonic seed phrase
Expand Down
1 change: 1 addition & 0 deletions sdk/src/gateway/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './common';
export * from './bitcoin-signer';
export * from './quote';
31 changes: 31 additions & 0 deletions sdk/src/gateway/utils/quote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { GatewayQuote } from '../generated-client/models/GatewayQuote';
import type { GatewayOnrampQuote } from '../generated-client/models/GatewayOnrampQuote';
import type { GatewayOfframpQuote } from '../generated-client/models/GatewayOfframpQuote';
import type { GatewayLayerZeroQuote } from '../generated-client/models/GatewayLayerZeroQuote';
import { instanceOfGatewayQuoteOneOf, type GatewayQuoteOneOf } from '../generated-client/models/GatewayQuoteOneOf';
import { instanceOfGatewayQuoteOneOf1, type GatewayQuoteOneOf1 } from '../generated-client/models/GatewayQuoteOneOf1';
import { instanceOfGatewayQuoteOneOf2, type GatewayQuoteOneOf2 } from '../generated-client/models/GatewayQuoteOneOf2';

export type InnerQuote = GatewayOnrampQuote | GatewayOfframpQuote | GatewayLayerZeroQuote;

/**
* Unwraps a GatewayQuote, returning the inner quote object directly.
*
* All three variants share common fields (inputAmount, outputAmount, fees,
* recipient, estimatedTimeInSecs, sender), so you can access them without
* caring about the variant:
*
* ```ts
* const inner = getInnerQuote(quote);
* console.log(inner.inputAmount.amount);
* console.log(inner.outputAmount.amount);
* console.log(inner.fees.amount);
* ```
*/
export function getInnerQuote(quote: GatewayQuote): InnerQuote {
const q = quote as object;
if (instanceOfGatewayQuoteOneOf(q)) return (q as GatewayQuoteOneOf).onramp;
if (instanceOfGatewayQuoteOneOf1(q)) return (q as GatewayQuoteOneOf1).offramp;
if (instanceOfGatewayQuoteOneOf2(q)) return (q as GatewayQuoteOneOf2).layerZero;
throw new Error('Unknown quote variant');
}
14 changes: 14 additions & 0 deletions sdk/src/mempool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,20 @@ export class MempoolClient {
return Infinity;
}

/**
* Get pending (unconfirmed) transactions for a Bitcoin address from the mempool.
*
* @param {string} address - The Bitcoin address to check.
* @returns {Promise<MempoolTxInfo[]>} Array of unconfirmed transactions.
*
* @example
* const mempoolClient = new MempoolClient();
* const pendingTxs = await mempoolClient.getAddressMempoolTxs('bc1q...');
*/
async getAddressMempoolTxs(address: string): Promise<MempoolTxInfo[]> {
return this.getJson<MempoolTxInfo[]>(`${this.basePath}/address/${address}/txs/mempool`);
}

/**
* @ignore
*/
Expand Down
6 changes: 5 additions & 1 deletion sdk/src/wallet/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export * from './utxo';

export { validate as isValidBtcAddress } from 'bitcoin-address-validation';
export {
validate as isValidBtcAddress,
getAddressInfo as getBtcAddressInfo,
AddressType as BtcAddressType,
} from 'bitcoin-address-validation';