@@ -10,75 +10,13 @@ import * as utxolib from '@bitgo/utxo-lib';
1010
1111const RECEIVE_ADDRESS = '' ;
1212const SEND_ADDRESS = '' ;
13- const MEMPOOL_PREFIX = omniConfig . coin === 'tbtc4' ? 'testnet4/' : '' ;
1413const AMOUNT = 729100000n ;
1514const ASSET_ID = 31 ;
16- const OMNI_PREFIX = Buffer . from ( '6f6d6e69' , 'hex' ) ;
1715
1816async function getWallet ( ) {
1917 return await omniConfig . sdk . coin ( omniConfig . coin ) . wallets ( ) . get ( { id : omniConfig . walletId } ) ;
2018}
2119
22- // eslint-disable-next-line @typescript-eslint/no-unused-vars
23- async function mintOmniAsset ( wallet : Wallet , address : string , feeRate = 20_000 ) {
24- const transactionVersion = Buffer . alloc ( 2 ) ;
25- const transactionType = Buffer . alloc ( 2 ) ;
26- transactionType . writeUint16BE ( 50 ) ;
27- const ecoSystem = Buffer . alloc ( 1 ) ;
28- ecoSystem . writeInt8 ( 2 ) ;
29- const propertyType = Buffer . alloc ( 2 ) ;
30- propertyType . writeUint16BE ( 2 ) ;
31- const previousPropertyID = Buffer . alloc ( 4 ) ;
32-
33- const category = Buffer . from ( 'Other\0' ) ;
34- const subCategory = Buffer . from ( 'Other\0' ) ;
35- const propertyTitle = Buffer . from ( 'Testcoin\0' ) ;
36- const propertyURL = Buffer . from ( 'https://example.com\0' ) ;
37- const propertyData = Buffer . from ( '\0' ) ;
38-
39- const amount = Buffer . alloc ( 8 ) ;
40- amount . writeBigUint64BE ( BigInt ( 100000 * 10 ** 8 ) ) ;
41-
42- const res = await superagent . get ( `https://mempool.space/${ MEMPOOL_PREFIX } api/address/${ address } /utxo` ) ;
43- const unspent = res . body [ 0 ] ;
44- const unspent_id = unspent . txid + ':' + unspent . vout ;
45-
46- const omniScript = Buffer . concat ( [
47- OMNI_PREFIX , // omni
48- transactionVersion ,
49- transactionType ,
50- ecoSystem ,
51- propertyType ,
52- previousPropertyID ,
53- category ,
54- subCategory ,
55- propertyTitle ,
56- propertyURL ,
57- propertyData ,
58- amount ,
59- ] ) ;
60-
61- const output = utxolib . payments . embed ( { data : [ omniScript ] , network : utxolib . networks . bitcoin } ) . output ;
62- if ( ! output ) {
63- throw new Error ( 'Invalid output' ) ;
64- }
65- const script = output . toString ( 'hex' ) ;
66- const tx = await wallet . sendMany ( {
67- recipients : [
68- {
69- amount : '0' ,
70- address : `scriptPubkey:${ script } ` ,
71- } ,
72- ] ,
73- isReplaceableByFee : true ,
74- feeRate,
75- walletPassphrase : omniConfig . walletPassphrase ,
76- changeAddress : address ,
77- unspents : [ unspent_id ] ,
78- } ) ;
79- console . log ( 'Omni asset created: ' , tx ) ;
80- }
81-
8220async function sendOmniAsset (
8321 wallet : Wallet ,
8422 receiver : string ,
@@ -87,7 +25,13 @@ async function sendOmniAsset(
8725 assetId = 31 ,
8826 feeRate = 20_000
8927) {
90- const res = await superagent . get ( `https://mempool.space/${ MEMPOOL_PREFIX } /api/address/${ sender } /utxo` ) ;
28+ if ( ! [ '1' , 'n' , 'm' ] . includes ( receiver . slice ( 0 , 1 ) ) ) {
29+ throw new Error (
30+ 'Omni has only been verified to work with legacy addresses - use other address formats at your own risk'
31+ ) ;
32+ }
33+
34+ const res = await superagent . get ( `https://mempool.space/${ omniConfig . MEMPOOL_PREFIX } api/address/${ sender } /utxo` ) ;
9135 const unspent = res . body [ 0 ] ;
9236 const unspent_id = unspent . txid + ':' + unspent . vout ;
9337
@@ -97,18 +41,22 @@ async function sendOmniAsset(
9741 assetHex . writeUInt32BE ( assetId ) ;
9842 const amountHex = Buffer . alloc ( 8 ) ;
9943 amountHex . writeBigUInt64BE ( amountMicroCents ) ;
100- const omniScript = Buffer . concat ( [ OMNI_PREFIX , transactionType , assetHex , amountHex ] ) ;
44+ const omniScript = Buffer . concat ( [ omniConfig . OMNI_PREFIX , transactionType , assetHex , amountHex ] ) ;
10145 const output = utxolib . payments . embed ( { data : [ omniScript ] , network : omniConfig . network } ) . output ;
10246 if ( ! output ) {
10347 throw new Error ( 'Invalid output' ) ;
10448 }
10549 const script = output . toString ( 'hex' ) ;
10650 const tx = await wallet . sendMany ( {
10751 recipients : [
52+ // this signals the receiver of the omni asset
53+ // we are not actually trying to send BTC to the receiver
54+ // so we send the minimum amount above the dust limit
10855 {
10956 amount : '546' ,
11057 address : receiver ,
11158 } ,
59+ // this is the actual script that the omni layer reads for the send
11260 {
11361 amount : '0' ,
11462 address : `scriptPubkey:${ script } ` ,
@@ -117,6 +65,8 @@ async function sendOmniAsset(
11765 isReplaceableByFee : true ,
11866 feeRate,
11967 walletPassphrase : omniConfig . walletPassphrase ,
68+ // we must send change to our input address to ensure that omni won't
69+ // accidentally send our asset to the change address instead of the recipient
12070 changeAddress : sender ,
12171 unspents : [ unspent_id ] ,
12272 } ) ;
@@ -129,7 +79,7 @@ async function sendOmniAsset(
12979async function main ( ) {
13080 console . log ( 'Starting...' ) ;
13181
132- const feeRateRes = await superagent . get ( `https://mempool.space/${ MEMPOOL_PREFIX } api/v1/fees/recommended` ) ;
82+ const feeRateRes = await superagent . get ( `https://mempool.space/${ omniConfig . MEMPOOL_PREFIX } api/v1/fees/recommended` ) ;
13383 const feeRate = feeRateRes . body . fastestFee ;
13484
13585 const wallet = await getWallet ( ) ;
0 commit comments