Skip to Content

Signature BTC

Guide de signature UTXO Bitcoin. Couvre la confirmation d’adresse et la signature P2PKH / P2SH-P2WPKH / P2WPKH / Taproot avec correspondance stricte des chemins et scripts, et des refTxs complets. Comportement aligné sur hardware-js-sdk (réponses Promise + événements d’interface).

Sommaire

  1. Fonctionnement
  2. Installation
  3. Initialisation
  4. Scénarios courants
  5. Interaction et état
  6. Exemples
  7. Validation et dépannage

Fonctionnement

Le signataire BTC OneKey utilise HardwareSDK et le protocole OneKey pour demander la vérification et la signature des UTXO sur l’appareil.

  • Les chemins doivent correspondre à l’objectif du script (44/49/84/86).
  • Fournissez les transactions précédentes complètes demandées par le processus de signature dans refTxs ; les exigences dépendent du type d’entrée et du micrologiciel.
  • L’appareil affiche les entrées, sorties, la monnaie rendue et les frais ; après confirmation, il renvoie des signatures ou une transaction sérialisée.

Installation

npm i @onekeyfe/hd-core @onekeyfe/hd-common-connect-sdk

Initialisation

Les exemples utilisent le portefeuille standard de façon cohérente. Pour un portefeuille caché, remplacez useEmptyPassphrase: true par la valeur vérifiée de passphraseState sur chaque appel d’adresse et de signature. Enregistrez les gestionnaires d’interface avant les appels protégés, et vérifiez success avant d’utiliser toute donnée renvoyée. Les exemples contenant des entrées de transaction déclarées sont des fragments de préparation, pas des applications autonomes exécutables.

import HardwareSDK from '@onekeyfe/hd-common-connect-sdk'; const initialized = await HardwareSDK.init({ env: 'webusb', fetchConfig: true, debug: false }); if (!initialized) throw new Error('SDK initialization failed'); const devices = await HardwareSDK.searchDevices(); if (!devices.success) throw new Error(devices.payload.error); if (!devices.payload.length) throw new Error("No device"); // Select explicitly in the application when more than one device is available. if (devices.payload.length !== 1) throw new Error('Select exactly one device before continuing'); const { connectId } = devices.payload[0]; if (!connectId) throw new Error("Missing connectId"); const state = await HardwareSDK.getDeviceState(connectId); if (!state.success) throw new Error(state.payload.error); const deviceId = state.payload.identity.deviceId; if (!deviceId) throw new Error("Device has no wallet identity");

Scénarios courants

Scénario 1 : obtenir une adresse

const res = await HardwareSDK.btcGetAddress(connectId, deviceId, { useEmptyPassphrase: true, path: "m/84'/0'/0'/0/0", coin: 'btc', showOnOneKey: true, }); if (!res.success) throw new Error(res.payload.error); // res.payload.address and res.payload.path are strings.

Paramètres

  • path : obligatoire ; doit correspondre à l’objectif.
  • coin : facultatif pour les demandes d’adresse ; par exemple, btc, test.
  • showOnOneKey? : facultatif ; afficher et confirmer sur l’appareil.

Valeur de retour

type AddressResult = | { success: true; payload: { address: string; path: string } } | { success: false; payload: { error: string; code?: string | number } };

Scénario 2 : signer une transaction

const { success, payload } = await HardwareSDK.btcSignTransaction(connectId, deviceId, { useEmptyPassphrase: true, coin: 'btc', inputs, outputs, refTxs, locktime: 0, }); if (!success) throw new Error(payload.error); // Verify payload.serializedTx and payload.signatures before broadcasting.

Paramètres

  • coin : obligatoire ; sélectionne les règles du réseau.
  • inputs : tableau obligatoire contenant :
    • address_n (chemin correspondant au script)
    • prev_hash (txid hexadécimal)
    • prev_index (vout)
    • amount (satoshis sous forme de chaîne)
    • script_type (SPENDADDRESS / SPENDP2SHWITNESS / SPENDWITNESS / SPENDTAPROOT)
  • outputs : tableau obligatoire contenant :
    • Destinataire : address + amount + script_type (par exemple, PAYTOADDRESS)
    • Monnaie rendue : address_n + amount + script_type conforme à l’objectif
  • refTxs : tableau obligatoire ; fournir toutes les transactions précédentes demandées par le micrologiciel. Utilisez un tableau vide uniquement si le processus de signature n’en nécessite aucune.
  • locktime? : facultatif.

Valeur de retour

type SignResult = | { success: true; payload: { serializedTx: string; signatures: string[]; txid?: string } } | { success: false; payload: { error: string; code?: string | number } };

Interaction et état

  • Les API se résolvent à la fin ; les demandes utilisateur arrivent via UI_REQUEST (déverrouiller l’appareil, confirmer les entrées/sorties/la monnaie rendue/les frais).
  • Exécutez les appels en série par appareil ; utilisez showOnOneKey pour confirmer les chemins de réception/de monnaie rendue avant de signer.

Exemples

Transaction P2SH-P2WPKH

Il s’agit d’un fragment de préparation. Remplacez les données UTXO/de sortie illustratives par votre transaction et chargez les éléments complets correspondants refTxs avant d’appeler le SDK.

import HardwareSDK from '@onekeyfe/hd-common-connect-sdk'; import type { BTCSignTransactionParams } from '@onekeyfe/hd-core'; const initialized = await HardwareSDK.init({ env: 'webusb', debug: false }); if (!initialized) throw new Error('SDK initialization failed'); const devices = await HardwareSDK.searchDevices(); if (!devices.success) throw new Error(devices.payload.error); if (!devices.payload.length) throw new Error("No device"); // Select explicitly in the application when more than one device is available. if (devices.payload.length !== 1) throw new Error('Select exactly one device before continuing'); const { connectId } = devices.payload[0]; if (!connectId) throw new Error("Missing connectId"); const state = await HardwareSDK.getDeviceState(connectId); if (!state.success) throw new Error(state.payload.error); const deviceId = state.payload.identity.deviceId; if (!deviceId) throw new Error("Device has no wallet identity"); const path49 = [(49 | 0x80000000) >>> 0, (0 | 0x80000000) >>> 0, (0 | 0x80000000) >>> 0, 0, 0]; const confirmedAddress = await HardwareSDK.btcGetAddress(connectId, deviceId, { path: path49, coin: 'btc', showOnOneKey: true, useEmptyPassphrase: true, }); if (!confirmedAddress.success) throw new Error(confirmedAddress.payload.error); const inputs: BTCSignTransactionParams['inputs'] = [ { address_n: path49, prev_index: 0, prev_hash: 'b035d89d4543ce5713c553d69431698116a822c57c03ddacf3f04b763d1999ac', amount: '3382047', script_type: 'SPENDP2SHWITNESS', }, ]; const outputs: BTCSignTransactionParams['outputs'] = [ { address_n: [(49 | 0x80000000) >>> 0, (0 | 0x80000000) >>> 0, (0 | 0x80000000) >>> 0, 1, 1], amount: '3181747', script_type: 'PAYTOP2SHWITNESS', // change }, { address: '18WL2iZKmpDYWk1oFavJapdLALxwSjcSk2', amount: '200000', script_type: 'PAYTOADDRESS', // recipient }, ]; // Load complete previous transactions matching each requested prev_hash. declare const refTxs: BTCSignTransactionParams['refTxs']; const { success, payload } = await HardwareSDK.btcSignTransaction(connectId, deviceId, { useEmptyPassphrase: true, coin: 'btc', inputs, outputs, refTxs, locktime: 0, }); if (!success) throw new Error(payload.error); // Verify the signed transaction before submitting it through your Bitcoin client.

Validation et dépannage

  • Chemin ↔ script : 44'→P2PKH, 49'→P2SH-P2WPKH, 84'→P2WPKH, 86'→P2TR.
  • refTxs doit contenir toutes les transactions précédentes demandées par le micrologiciel ; les données demandées manquantes entraînent un rejet.
  • La sortie de monnaie rendue doit rester dans le même chemin de compte.
  • Vérifiez sur l’appareil : entrées, sorties, monnaie rendue et frais doivent correspondre à votre interface.
  • Vérification sur l’hôte : reconstruire avec bitcoinjs-lib / @scure/btc-signer, vérifier serializedTx/txid et les signatures.
  • Problèmes courants :
    • Trop d’entrées : signalez la limite. Diviser ou simplifier une transaction nécessite de la reconstruire et d’obtenir une nouvelle vérification de l’utilisateur.
    • Anomalie de frais : arrêtez la signature. Recalculez les sorties, la monnaie rendue et les seuils de poussière avec l’utilisateur ; ne modifiez pas silencieusement une transaction déjà examinée.
    • Refus utilisateur/délai dépassé : proposer de réessayer ou d’annuler ; aucune nouvelle soumission automatique.

Voir la documentation des méthodes : btcSignTransaction · btcGetAddress.

Dernière mise à jour le