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
60 changes: 60 additions & 0 deletions examples/ts/create-descriptor-wallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { BitGoAPI } from '@bitgo/sdk-api';
import { Tbtc } from '@bitgo/sdk-coin-btc'; // Replace with your given coin (e.g. Ltc, Tltc)
import { AbstractUtxoCoin, descriptor } from '@bitgo/abstract-utxo';
require('dotenv').config({ path: '../../.env' });

const bitgo = new BitGoAPI({
accessToken: process.env.TESTNET_ACCESS_TOKEN,
env: 'test', // Change this to env: 'production' when you are ready for production
});

// Set the coin name to match the blockchain and network
// btc = bitcoin, tbtc = testnet bitcoin
const coin = 'tbtc';
bitgo.register(coin, Tbtc.createInstance);

// TODO: set a label for your new wallet here
const label = 'Example Descriptor Wallet';

// TODO: set your passphrase for your new wallet here
const passphrase = 'test_wallet_passphrase';

// TODO: set your enterprise ID for your new wallet here
const enterprise = 'your_enterprise_id';

async function main() {
console.log(
// this wrapper creates three keys: userKey, backupKey, and bitgoKey
// at the moment, this is a somewhat artificial requirement from wallet platform
// in the future, we will allow for more flexible key generation
await descriptor.createWallet.createDescriptorWalletWithWalletPassphrase(
bitgo,
bitgo.coin(coin) as AbstractUtxoCoin,
{
label,
walletPassphrase: passphrase,
enterprise,
descriptorsFromKeys(userKey, cosigners) {
// userKey is backed up at BitGo with the wallet passphrase
// cosigners are backup key and BitGo key
const xpubs = [userKey, ...cosigners].map((key) => key.neutered().toBase58());

return [
// here is a single-sig descriptor for the user key
descriptor.createNamedDescriptorWithSignature('SingleSigWpkh', `wpkh(${xpubs[0]}/*)`, userKey),
// here is a 2of3 multisig descriptor for the backup key and BitGo key
descriptor.createNamedDescriptorWithSignature(
'MultiSigWsh',
`wsh(multi(2,${xpubs.map((xpub) => `${xpub}/*`).join(',')})`,
userKey
),
// equivalent to the above, but returns two descriptors (external and internal)
...descriptor.createWallet.DefaultWsh2Of3(userKey, cosigners),
];
},
}
)
);
}

main().catch((e) => console.log(e));
5 changes: 4 additions & 1 deletion modules/abstract-utxo/src/descriptor/NamedDescriptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ export type NamedDescriptor<T = string> = {

export function createNamedDescriptorWithSignature(
name: string,
descriptor: Descriptor,
descriptor: string | Descriptor,
signingKey: BIP32Interface
): NamedDescriptor {
if (typeof descriptor === 'string') {
descriptor = Descriptor.fromString(descriptor, 'derivable');
}
const value = descriptor.toString();
const signature = signMessage(value, signingKey, networks.bitcoin).toString('hex');
return { name, value, signatures: [signature] };
Expand Down
2 changes: 1 addition & 1 deletion modules/abstract-utxo/src/descriptor/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export { Miniscript, Descriptor } from '@bitgo/wasm-miniscript';
export { assertDescriptorWalletAddress } from './assertDescriptorWalletAddress';
export { NamedDescriptor, createNamedDescriptorWithSignature } from './NamedDescriptor';
export { NamedDescriptor, createNamedDescriptorWithSignature, hasValidSignature } from './NamedDescriptor';
export { isDescriptorWallet, getDescriptorMapFromWallet } from './descriptorWallet';
export { getPolicyForEnv } from './validatePolicy';
export * as createWallet from './createWallet';
Loading