├── .gitignore ├── Bitcoin_php.jpg ├── Indonesian ├── README2_Indonesian.md ├── README3_Indonesian.md ├── README4_Indonesian.md ├── README5_Indonesian.md └── README_Indonesian.md ├── README-japanese-lang.md ├── README-russian.md ├── README-spanish.md ├── README-zhchs.md ├── README.md ├── README2-russian.md ├── README2-spanish.md ├── README2-zhchs.md ├── README2.md ├── README2_Brazilian_Portuguese.md ├── README3-russian.md ├── README3-spanish.md ├── README3-zhchs.md ├── README3.md ├── README3_Brazilian_Portuguese.md ├── README4-russian.md ├── README4-spanish.md ├── README4-zhchs.md ├── README4.md ├── README4_Brazilian_Portuguese.md ├── README5-russian.md ├── README5-zhchs.md ├── README5.md ├── README5_Brazilian_Portuguese.md ├── README6-zhchs.md ├── README6.md ├── README_Brazilian_Portuguese.md ├── app.php ├── bitcoin-transfer-to-bot.jpg ├── bitcoin_wallet.php ├── call_apis.php ├── click-link-to-pay.jpg ├── composer.json ├── config-example.php ├── helloworld.jpeg ├── helloworld.php ├── mixin_network-keys.jpg ├── newuser-transfer-bitcoin-to-me.jpg ├── others ├── TEST_README.md ├── app-coin-exchange.php ├── chat-client.php ├── chat.php ├── coin_exchange.php ├── createUser.php ├── hardcode.php ├── ratchetClient.php ├── searchUser.php └── wrenchClient.php ├── pay-links.jpg ├── php-eth.jpg ├── res ├── btc-usdt-price.jpg ├── exchange-and-balance.jpg ├── help.jpg ├── user-directly-exchage-result.jpg └── user-exchange-bitcoin-directly.jpg └── test └── call_user_func_example.php /.gitignore: -------------------------------------------------------------------------------- 1 | .git 2 | composer.lock 3 | composer.phar 4 | vendor 5 | config.php 6 | new_users.csv 7 | config-my.php 8 | .DS_Store 9 | res/.DS_Store 10 | -------------------------------------------------------------------------------- /Bitcoin_php.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/Bitcoin_php.jpg -------------------------------------------------------------------------------- /Indonesian/README2_Indonesian.md: -------------------------------------------------------------------------------- 1 | # Tutorial PHP Bitcoin berdasarkan Mixin Network II: Menerima dan mengirim Bitcoin di Mixin Messenger 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | Pada [Bab sebelumnya](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/Indonesian/README_Indonesian.md), bot pertama Anda hanya berfungsi. Pesan gema bot dari pengguna. 5 | 6 | Buat file app.php dengan kode berikut: 7 | ```php 8 | 15 17 | ]); 18 | class callTraitClass { 19 | use MixinSDKTrait; 20 | public $config; 21 | public function __construct() 22 | { 23 | $config = require(__DIR__.'/config.php'); 24 | $this->config = $config; 25 | } 26 | } 27 | $callTrait = new callTraitClass(); 28 | $Token = $callTrait->getToken('GET', '/', ''); 29 | print_r($callTrait->config['client_id']); 30 | // $Header = 'Authorization'.'Bearer '.$Token; 31 | // print($Header); 32 | $connector = new \Ratchet\Client\Connector($loop,$reactConnector); 33 | // $connector('ws://127.0.0.1:9000', ['protocol' => 'Mixin-Blaze-1'], ['Origin' => 'http://localhost', 34 | $connector('wss://blaze.mixin.one', ['protocol' => 'Mixin-Blaze-1'],[ 35 | 'Authorization' => 'Bearer '.$Token 36 | ]) 37 | ->then(function(Ratchet\Client\WebSocket $conn) { 38 | $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) { 39 | $jsMsg = json_decode(gzdecode($msg)); 40 | print_r($jsMsg); 41 | if ($jsMsg->action === 'CREATE_MESSAGE' and property_exists($jsMsg,'data')) { 42 | echo "\nNeed reply server a receipt!\n"; 43 | $RspMsg = generateReceipt($jsMsg->data->message_id); 44 | $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY); 45 | $conn->send($msg); 46 | if ($jsMsg->data->category === 'PLAIN_TEXT') { 47 | echo "PLAIN_TEXT:".base64_decode($jsMsg->data->data); 48 | $isCmd = strtolower(base64_decode($jsMsg->data->data)); 49 | if ($isCmd ==='?' or $isCmd ==='help') { 50 | $msgData = sendUsage($jsMsg->data->conversation_id); 51 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 52 | $conn->send($msg); 53 | } elseif ($isCmd === '1') { 54 | // print($callTrait->config['client_id']); 55 | $msgData = sendAppButtons($jsMsg); 56 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 57 | $conn->send($msg); 58 | }//end of pay1 59 | elseif ($isCmd === '2') { 60 | // print($callTrait->config['client_id']); 61 | $msgData = sendAppCard($jsMsg); 62 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 63 | $conn->send($msg); 64 | }//end of pay2 65 | elseif ($isCmd === '3') { 66 | transfer(); 67 | } else { 68 | $msgData = sendPlainText($jsMsg->data->conversation_id, 69 | base64_decode($jsMsg->data->data)); 70 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 71 | $conn->send($msg); 72 | } 73 | } //end of PLAIN_TEXT 74 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 75 | // refundInstant 76 | echo "user id:".$jsMsg->data->user_id; 77 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 78 | print_r($dtPay); 79 | if ($dtPay->amount > 0) { 80 | echo "paid!".$dtPay->asset_id; 81 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 82 | } 83 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 84 | } //end of CREATE_MESSAGE 85 | }); 86 | $conn->on('close', function($code = null, $reason = null) { 87 | echo "Connection closed ({$code} - {$reason})\n"; 88 | }); 89 | /* start listen for the incoming message */ 90 | $message = [ 91 | 'id' => Uuid::uuid4()->toString(), 92 | 'action' => 'LIST_PENDING_MESSAGES', 93 | ]; 94 | print_r(json_encode($message)); 95 | $msg = new Frame(gzencode(json_encode($message)),true,Frame::OP_BINARY); 96 | $conn->send($msg); 97 | // $conn->send(gzencode($msg,1,FORCE_DEFLATE)); 98 | }, function(\Exception $e) use ($loop) { 99 | echo "Could not connect: {$e->getMessage()}\n"; 100 | $loop->stop(); 101 | }); 102 | $loop->run(); 103 | function sendUsage($conversation_id):Array { 104 | $msgHelp = << $conversation_id, 115 | 'category' => 'PLAIN_TEXT', 116 | 'status' => 'SENT', 117 | 'message_id' => Uuid::uuid4()->toString(), 118 | 'data' => base64_encode($msgContent),//base64_encode("hello!"), 119 | ]; 120 | $msgPayButton = [ 121 | 'id' => Uuid::uuid4()->toString(), 122 | 'action' => 'CREATE_MESSAGE', 123 | 'params' => $msgParams, 124 | ]; 125 | return $msgPayButton; 126 | } 127 | function sendAppButtons($jsMsg):Array { 128 | $payLinkEOS = "https://mixin.one/pay?recipient=". 129 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 130 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 131 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 132 | "&memo="; 133 | $payLinkBTC = "https://mixin.one/pay?recipient=". 134 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 135 | "c6d0c728-2624-429b-8e0d-d9d19b6592fa". 136 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 137 | "&memo="; 138 | $msgData = [[ 139 | 'label' => "Pay 0.001 EOS", 140 | 'color' => "#FFABAB", 141 | 'action' => $payLinkEOS, 142 | ],[ 143 | 'label' => "Pay 0.0001 BTC", 144 | 'color' => "#00EEFF", 145 | 'action' => $payLinkBTC, 146 | ], 147 | ]; 148 | $msgParams = [ 149 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 150 | // 'recipient_id' => $jsMsg->data->user_id, 151 | 'category' => 'APP_BUTTON_GROUP',//'PLAIN_TEXT', 152 | 'status' => 'SENT', 153 | 'message_id' => Uuid::uuid4()->toString(), 154 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 155 | ]; 156 | $msgPayButtons = [ 157 | 'id' => Uuid::uuid4()->toString(), 158 | 'action' => 'CREATE_MESSAGE', 159 | 'params' => $msgParams, 160 | ]; 161 | return $msgPayButtons; 162 | } 163 | function sendAppCard($jsMsg):Array 164 | { 165 | $payLink = "https://mixin.one/pay?recipient=". 166 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 167 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 168 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 169 | "&memo="; 170 | $msgData = [ 171 | 'icon_url' => "https://mixin.one/assets/98b586edb270556d1972112bd7985e9e.png", 172 | 'title' => "Pay 0.001 EOS", 173 | 'description' => "pay", 174 | 'action' => $payLink, 175 | ]; 176 | $msgParams = [ 177 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 178 | // 'recipient_id' => $jsMsg->data->user_id, 179 | 'category' => 'APP_CARD',//'PLAIN_TEXT', 180 | 'status' => 'SENT', 181 | 'message_id' => Uuid::uuid4()->toString(), 182 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 183 | ]; 184 | $msgPayButton = [ 185 | 'id' => Uuid::uuid4()->toString(), 186 | 'action' => 'CREATE_MESSAGE', 187 | 'params' => $msgParams, 188 | ]; 189 | return $msgPayButton; 190 | } 191 | function transfer() { 192 | $mixinSdk = new MixinSDK(require './config.php'); 193 | print_r($mixinSdk->getConfig()); 194 | } 195 | function generateReceipt($msgID):Array { 196 | $IncomingMsg = ["message_id" => $msgID, "status" => "READ"]; 197 | $RspMsg = ["id" => Uuid::uuid4()->toString(), "action" => "ACKNOWLEDGE_MESSAGE_RECEIPT", 198 | "params" => $IncomingMsg]; 199 | return $RspMsg; 200 | } 201 | function refundInstant($_assetID,$_amount,$_opponent_id) { 202 | $mixinSdk = new MixinSDK(require './config.php'); 203 | // print_r(); 204 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 205 | $mixinSdk->getConfig()['default']['pin'],$_amount); 206 | print_r($BotInfo); 207 | } 208 | ``` 209 | ### Halo Bitcoin 210 | Jalankan php app.php di direktori proyek. 211 | ```bash 212 | php app.php 213 | ``` 214 | ```bash 215 | wenewzha:mixin_labs-php-bot wenewzhang$ php app.php 216 | a1ce2967-a534-417d-bf12-c86571e4eefa{"id":"12c7a470-d6a4-403d-94e8-e6f8ae833971","action":"LIST_PENDING_MESSAGES"}stdClass Object 217 | ( 218 | [id] => 12c7a470-d6a4-403d-94e8-e6f8ae833971 219 | [action] => LIST_PENDING_MESSAGES 220 | ) 221 | ``` 222 | Bot terhubung ke mixin.one berhasil ketika konsol menampilkan "LIST_PENDING_MESSAGES". 223 | ![pay-links](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/pay-links.jpg) 224 | 225 | 226 | Bot telah memberi tahu Anda cara berinteraksi: 227 | - **1** bot mengirim tautan APP_CARD. 228 | - **2** bot mengirim tautan APP_BUTTON_GROUP. 229 | - **?** atau untuk bantuan ! anda dapat 230 | Klik tautan di halaman obrolan, masukkan kode PIN untuk membayar koin ke bot. 231 | ![click-pay-link-to-pay](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/click-link-to-pay.jpg) 232 | 233 | Panduan Lengkap [Pengantar Pesan Mixin](https://developers.mixin.one/api/beta-mixin-message/websocket-messages/). 234 | 235 | Pengguna dapat membayar 0,001 Bitcoin ke bot, Bitcoin 0,001 akan dikembalikan dalam 1 detik. Bahkan, pengguna dapat membayar koin apa pun. 236 | ![pay-link](https://github.com/wenewzhang/mixin_network-nodejs-bot2/raw/master/Pay_and_refund_quickly.jpg) 237 | 238 | Pengembang dapat mengirim Bitcoin ke bot mereka di halaman obrolan. Bot akan mengirim kembali segera setelah menerima Bitcoin. 239 | ![transfer Bitcoin](https://github.com/wenewzhang/mixin_network-nodejs-bot2/raw/master/transfer-any-tokens.jpg) 240 | 241 | ## Ringkasan Kode Summary 242 | ```php 243 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 244 | $conn->send($msg); 245 | ``` 246 | Bot mengirim pesan ke pengguna, yang menggunakan json serialize dan kemudian menggunakan gzencode kompres. 247 | ```php 248 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 249 | // refundInstant 250 | echo "user id:".$jsMsg->data->user_id; 251 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 252 | print_r($dtPay); 253 | if ($dtPay->amount > 0) { 254 | echo "paid!".$dtPay->asset_id; 255 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 256 | } 257 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 258 | ``` 259 | * Jumlah $ dtPay-> negatif jika bot berhasil mengirim Bitcoin ke pengguna. 260 | * Jumlah $ dtPay-> positif jika bot menerima Bitcoin. 261 | 262 | Kode berikut mentransfer Bitcoin ke pengguna. 263 | ```php 264 | function refundInstant($_assetID,$_amount,$_opponent_id) { 265 | $mixinSdk = new MixinSDK(require './config.php'); 266 | // print_r(); 267 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 268 | $mixinSdk->getConfig()['default']['pin'],$_amount); 269 | print_r($BotInfo); 270 | } 271 | ``` 272 | 273 | Kode lengkap ada [disini](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/app.php) 274 | -------------------------------------------------------------------------------- /Indonesian/README4_Indonesian.md: -------------------------------------------------------------------------------- 1 | # Bagaimana cara berdagang bitcoin melalui bahasa PHP 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | ## Solusi Pertama: bayar ke API ExinCore 5 | [Exincore](https://github.com/exinone/exincore) provide a commercial trading API on Mixin Network. 6 | 7 | Anda membayar USDT ke ExinCore, ExinCore mentransfer Bitcoin kepada Anda dengan cepat dengan biaya yang sangat rendah dan harga yang wajar. Setiap transaksi bersifat anonim untuk umum tetapi masih dapat diverifikasi di blockchain explorer. Hanya Anda dan ExinCore yang tahu detailnya. 8 | 9 | ExinCore tidak tahu siapa Anda karena ExinCore hanya tahu uuid klien Anda. 10 | 11 | ### Pra-permintaan: 12 | Anda seharusnya membuat bot berdasarkan pada Mixin Network. Buat satu dengan membaca [Tutorial PHP Bitcoin](https://github.com/wenewzhang/mixin_labs-php-bot). 13 | 14 | #### Instal paket yang diperlukan 15 | Seperti yang Anda ketahui, kami memperkenalkan Anda mixin-sdk-php di[bab 1](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README.md), anggap sudah diinstal sebelumnya, mari kita instal **uuid, msgpack** disini. 16 | ```bash 17 | composer require ramsey/uuid 18 | composer require rybakit/msgpack 19 | ``` 20 | #### Setor (Deposit) USDT atau Bitcoin ke akun Mixin Network Anda dan lihat saldo 21 | ExinCore dapat bertukar antara Bitcoin, USDT, EOS, Eth dll. Di sini menunjukkan kepada Anda cara bertukar antara USDT dan Bitcoin, 22 | Periksa saldo & alamat dompet sebelum Anda melakukan pemesanan. 23 | 24 | - Periksa alamat & saldo, ingat alamat dompet Bitcoin. 25 | - Setor (Deposit) Bitcoin ke alamat dompet Bitcoin ini. 26 | - Periksa saldo Bitcoin setelah 100 menit kemudian. 27 | 28 | **Ngomong-ngomong, alamat Bitcoin & USDT sama.** 29 | 30 | ```php 31 | if ($line == '2') { 32 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 33 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 34 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 35 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 36 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 37 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 38 | } 39 | fclose($handle); 40 | } else print("Create user first\n"); 41 | } 42 | if ($line == '3') { 43 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 44 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 45 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 46 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(USDT_ASSET_ID); 47 | print_r("USDT wallet address is :".$asset_info["public_key"]."\n"); 48 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 49 | } 50 | fclose($handle); 51 | } else print("Create user first\n"); 52 | } 53 | ``` 54 | #### Lihat harga pasar 55 | Bagaimana cara mengecek harga koin? Anda perlu memahami apa koin dasar. Jika Anda ingin membeli Bitcoin dan menjual USDT, USDT adalah koin dasar. Jika Anda ingin membeli USDT dan menjual Bitcoin, Bitcoin adalah koin dasar. 56 | ```php 57 | function getExchangeCoins($base_coin) :string { 58 | $client = new GuzzleHttp\Client(); 59 | $res = $client->request('GET', 'https://exinone.com/exincore/markets?base_asset='.$base_coin, [ 60 | ]); 61 | $result = ""; 62 | if ($res->getStatusCode() == "200") { 63 | // echo $res->getStatusCode() . PHP_EOL; 64 | $resInfo = json_decode($res->getBody(), true); 65 | echo "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 66 | $result = "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 67 | foreach ($resInfo["data"] as $key => $coinInfo) { 68 | echo ($coinInfo["exchange_asset"] ." ".$coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 69 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "); 70 | $result .= $coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 71 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "; 72 | foreach ($coinInfo["exchanges"] as $key => $exchange) { 73 | echo $exchange . " "; 74 | $result .= $exchange . " "; 75 | } 76 | echo PHP_EOL; 77 | $result .= PHP_EOL; 78 | } 79 | } 80 | return $result; 81 | } 82 | ``` 83 | 84 | #### Buat memo untuk menyiapkan pesanan 85 | Bab 2: [Echo Bitcoin](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2.md) memperkenalkan koin transfer. Tetapi Anda harus memberi tahu ExinCore koin mana yang ingin Anda beli. Cukup tulis aset target Anda ke dalam memo. 86 | ```php 87 | $memo = base64_encode(MessagePack::pack([ 88 | 'A' => Uuid::fromString($_targetAssetID)->getBytes(), 89 | ])); 90 | ``` 91 | #### Bayar BTC ke gateway API dengan memo yang dihasilkan 92 | Transfer Bitcoin(BTC_ASSET_ID) to ExinCore(EXIN_BOT), menempatkan Anda menargetkan aset uuid di memo, jika tidak, ExinCore akan mengembalikan uang Anda segera! 93 | ```php 94 | const EXIN_BOT = "61103d28-3ac2-44a2-ae34-bd956070dab1"; 95 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 96 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 97 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 98 | coinExchange(BTC_ASSET_ID,"0.0001",USDT_ASSET_ID); 99 | 100 | //........... 101 | 102 | function coinExchange($_assetID,$_amount,$_targetAssetID) { 103 | $mixinSdk = new MixinSDK(require './config.php'); 104 | // print_r(); 105 | $memo = base64_encode(MessagePack::pack([ 106 | 'A' => Uuid::fromString($_targetAssetID)->getBytes(), 107 | ])); 108 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,EXIN_BOT, 109 | $mixinSdk->getConfig()['default']['pin'],$_amount,$memo); 110 | print_r($BotInfo); 111 | } 112 | ``` 113 | ExinCore harus mentransfer koin target ke bot Anda, sementara itu, masukkan biaya, id pesanan, harga dll. informasi dalam memo itu, bukalah data seperti di bawah ini. 114 | - **readUserSnapshots** Baca snapshot dari pengguna. 115 | ```php 116 | $limit = 20; 117 | $offset = '2019-03-10T01:58:25.362528Z'; 118 | $snapInfo = $mixinSdk_BotInstance->Wallet()->readUserSnapshots($limit, $offset); 119 | // print_r($networkInfo2); 120 | foreach ($snapInfo as $record) { 121 | // echo $key . PHP_EOL; 122 | // print_r($record); 123 | if ($record['amount'] > 0 and $record['memo'] != '') { 124 | echo "------------MEMO:-coin--exchange--------------" . PHP_EOL; 125 | echo "memo: " . $record['memo'] . PHP_EOL; 126 | // print_r($dtPay->memo); 127 | echo "You Get Coins: ". $record['asset_id']. " " . $record['amount'] . PHP_EOL; 128 | $memoUnpack = MessagePack::unpack(base64_decode($record['memo'])); 129 | $feeAssetID = Uuid::fromBytes($memoUnpack['FA'])->toString(); 130 | $OrderID = Uuid::fromBytes($memoUnpack['O'])->toString(); 131 | if ($memoUnpack['C'] == 1000) { 132 | echo "Successful Exchange:". PHP_EOL; 133 | echo "Fee asset ID: " . $feeAssetID . " fee is :" . $memoUnpack['F'] . PHP_EOL; 134 | echo "Order ID: " . $OrderID . " Price is :" . $memoUnpack['P'] . PHP_EOL; 135 | } else print_r($memoUnpack); 136 | echo "--------------memo-record end---------------" . PHP_EOL; 137 | } 138 | } 139 | ``` 140 | 141 | Jika pertukaran uang Anda berhasil, hasilkan konsol seperti di bawah ini: 142 | ```bash 143 | ------------MEMO:-coin--exchange-------------- 144 | memo: hqFDzQPooVCnMzg3Mi45N6FGqTAuMDAwNzc0NqJGQcQQgVsLGidkNzaPqkLWlPpiCqFUoUahT8QQIbfeL6p5RVOcEP0mLb+t+g== 145 | You Get Coins: 815b0b1a-2764-3736-8faa-42d694fa620a 0.3857508 146 | Successful Exchange: 147 | Fee asset ID: 815b0b1a-2764-3736-8faa-42d694fa620a fee is :0.0007746 148 | Order ID: 21b7de2f-aa79-4553-9c10-fd262dbfadfa Price is :3872.97 149 | --------------memo-record end--------------- 150 | ``` 151 | 152 | #### Lihat saldo Bitcoin 153 | Periksa saldo dompet. 154 | ```php 155 | $mixinSdk = new MixinSDK(require './config.php'); 156 | $asset_info = $mixinSdk->Wallet()->readAsset(USDT_ASSET_ID); 157 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 158 | ``` 159 | ## Penggunaan kode sumber 160 | Jalankan **php call_apis.php** untuk menjalankannya. 161 | 162 | - 1: Buat pengguna dan perbarui PIN 163 | - 2: Lihat saldo & alamat Bitcoin 164 | - 3: Lihat saldo & alamat USDT 165 | - 4: Lihat saldo EOS 166 | - 5: Lihat alamat EOS 167 | - 6: Transfer Bitcoin dari bot ke pengguna baru 168 | - 7: Transfer Bitcoin dari pengguna baru ke Master 169 | - 8: Tarik (Withdraw) Bitcoin bot 170 | - 9: Tarik (Withdraw) EOS bot 171 | - qu: Lihat harga pasar (USDT) 172 | - qb: Lihat harga pasar (BTC) 173 | - b: Saldo bot (USDT & BTC) 174 | - s: Lihat Snapshots 175 | - tb: Transfer 0,0001 BTC, beli USDT 176 | - tu: Transfer $ 1 USDT, beli BTC 177 | - q: Keluar 178 | 179 | [Lengkap Kode Sumber](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/call_apis.php) 180 | 181 | ## Solusi Kedua: Daftarkan pesanan Anda di bursa Ocean.One 182 | -------------------------------------------------------------------------------- /Indonesian/README5_Indonesian.md: -------------------------------------------------------------------------------- 1 | # Bagaimana cara berdagang bitcoin melalui PHP 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | Exincore diperkenalkan dalam [bab terakhir](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README4.md), Anda dapat bertukar banyak aset kripto dengan harga pasar dan menerima aset Anda dalam 1 detik. Jika Anda ingin memperdagangkan aset dengan harga terbatas, atau memperdagangkan aset tidak didukung oleh ExinCore sekarang, Ocean.One adalah jawabannya. 5 | 6 | ## Solusi Kedua: Daftarkan pesanan Anda di bursa Ocean.One 7 | [Ocean.one](https://github.com/mixinNetwork/ocean.one) adalah pertukaran terdesentralisasi yang dibangun di atas Mixin Network, hampir pertama kali pertukaran terdesentralisasi mendapatkan pengalaman pengguna yang sama dengan yang terpusat. 8 | 9 | Anda dapat membuat daftar aset apa pun di Ocean.One. Bayar aset yang ingin Anda jual ke akun Ocean.One, tulis permintaan Anda di memo pembayaran, Ocean.One akan mencantumkan pesanan Anda ke pasar. Ini mengirim aset ke dompet Anda setelah pesanan Anda cocok. 10 | 11 | * Tidak perlu mendaftar 12 | * Tidak diperlukan deposit 13 | * Tidak ada proses daftar. 14 | 15 | ### Pra-permintaan: 16 | Anda seharusnya membuat bot berdasarkan pada Mixin Network. Buat satu dengan membaca [Tutorial PHP Bitcoin](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README.md). 17 | 18 | #### Instal paket yang diperlukan 19 | [Bab 4](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README4.md) memperkenalkan [**mixin-sdk-php**](https://packagist.org/packages/exinone/mixin-sdk-php) untuk Anda, anggap sudah diinstal sebelumnya. 20 | 21 | #### Deposit USDT atau Bitcoin ke akun Mixin Network Anda dan baca saldo 22 | Ocean.one dapat mencocokkan pesanan apa pun. Di sini kami bertukar antara USDT dan Bitcoin, Periksa saldo & alamat dompet sebelum Anda melakukan pemesanan. 23 | 24 | - Periksa alamat & saldo, temukan alamat dompet Bitcoin itu. 25 | - Deposit Bitcoin ke alamat dompet Bitcoin ini. 26 | - Periksa saldo Bitcoin setelah 100 menit kemudian. 27 | 28 | **Alamat Omni USDT sama dengan alamat Bitcoin** 29 | 30 | ```php 31 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 32 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 33 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 34 | 35 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 36 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 37 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 38 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 39 | ``` 40 | 41 | #### Baca buku pesanan dari Ocean.one 42 | Bagaimana cara memeriksa harga koin? Anda perlu memahami apa koin dasar. Jika Anda ingin membeli Bitcoin dan menjual USDT, USDT adalah koin dasar. Jika Anda ingin membeli USDT dan menjual Bitcoin, Bitcoin adalah koin dasar. 43 | 44 | 45 | ```php 46 | if ( $ocmd == '1') { getOceanOneMarketInfos(XIN_ASSET_ID,USDT_ASSET_ID);} 47 | function getOceanOneMarketInfos($targetCoin, $baseCoin) { 48 | $client = new GuzzleHttp\Client(); 49 | $baseUrl = "https://events.ocean.one/markets/".$targetCoin."-".$baseCoin."/book"; 50 | $res = $client->request('GET', $baseUrl, [ 51 | ]); 52 | if ($res->getStatusCode() == "200") { 53 | // echo $res->getStatusCode() . PHP_EOL; 54 | $resInfo = json_decode($res->getBody(), true); 55 | echo "Side | Price | Amount | Funds" . PHP_EOL; 56 | foreach ($resInfo["data"]["data"]["asks"] as $key => $exchange) { 57 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 58 | } 59 | foreach ($resInfo["data"]["data"]["bids"] as $key => $exchange) { 60 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 61 | } 62 | } 63 | } 64 | ``` 65 | 66 | #### Buat memo untuk menyiapkan pesanan 67 | Bab 2: [Echo Bitcoin](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2.md) memperkenalkan koin transfer. Tetapi Anda harus memberi tahu Ocean.one. Seseorang tahu koin mana yang ingin Anda beli. 68 | - **sisi** "B" atau "A", "B" untuk beli, "A" untuk jual. 69 | - **aset** UUID dari aset yang ingin Anda beli 70 | - **harga** Jika Sisi adalah "B", Harga adalah Aset UUID; jika Sidi adalah "A", Harga adalah aset yang ditransfer ke Ocean.one. 71 | 72 | ```php 73 | function GenerateOrderMemo($side, $asset, $price) :string { 74 | $memo = base64_encode(MessagePack::pack([ 75 | 'S' => $side, 76 | 'A' => Uuid::fromString($asset)->getBytes(), 77 | 'P' => $price, 78 | 'T' => 'L', 79 | ])); 80 | return $memo; 81 | } 82 | ``` 83 | 84 | #### Bayar BTC ke OceanOne dengan memo yang dihasilkan 85 | Transfer Bitcoin (BTC_ASSET_ID) ke Ocean.one (OCEANONE_BOT), membuat Anda menargetkan aset uuid (USDT) dalam memo itu. 86 | 87 | ```php 88 | const OCEANONE_BOT = "aaff5bef-42fb-4c9f-90e0-29f69176b7d4"; 89 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 90 | const XIN_ASSET_ID = "c94ac88f-4671-3976-b60a-09064f1811e8"; 91 | 92 | if ( $ocmd == 's1') { 93 | $p = readline("Input the Price of XIN/USDT: "); 94 | $a = readline("Input the Amount of XIN: "); 95 | $tMemo = GenerateOrderMemo("A",USDT_ASSET_ID,$p); 96 | echo $tMemo . PHP_EOL; 97 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 98 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(XIN_ASSET_ID); 99 | print_r($asset_info); 100 | if ( (float) $asset_info["balance"] >= (float) $a ) { 101 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(XIN_ASSET_ID,OCEANONE_BOT, 102 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 103 | $a, 104 | $tMemo); 105 | print_r($transInfos); 106 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 107 | } else { echo "Not enough XIN!\n";} 108 | } 109 | ``` 110 | 111 | Jika Anda ingin membeli XIN, sebut saja seperti di bawah ini: 112 | 113 | ```php 114 | if ( $ocmd == 'b1') { 115 | $p = readline("Input the Price of XIN/USDT: "); 116 | $a = readline("Input the Amount of USDT: "); 117 | $tMemo = GenerateOrderMemo("B",XIN_ASSET_ID,$p); 118 | echo $tMemo . PHP_EOL; 119 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 120 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(USDT_ASSET_ID); 121 | 122 | print_r($asset_info); 123 | if ( ((float) $asset_info["balance"] >= 1) && ( (float) $asset_info["balance"] >= (float) $a ) ) { 124 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(USDT_ASSET_ID,OCEANONE_BOT, 125 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 126 | $a, 127 | $tMemo); 128 | print_r($transInfos); 129 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 130 | } else { echo "Not enough USDT!\n";} 131 | } 132 | ``` 133 | 134 | Output pesanan sukses seperti di bawah ini: 135 | ```bash 136 | Input the Price of XIN/USDT: 112 137 | Input the Amount of USDT: 1 138 | hKFToUKhQcQQyUrIj0ZxOXa2CgkGTxgR6KFQozExMqFUoUw= 139 | client id is:26b20aa5-40c0-3e00-9de0-666cfb6f2daa 140 | Array 141 | ( 142 | [type] => asset 143 | [asset_id] => 815b0b1a-2764-3736-8faa-42d694fa620a 144 | [chain_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa 145 | [symbol] => USDT 146 | [name] => Tether USD 147 | [icon_url] => https://images.mixin.one/ndNBEpObYs7450U08oAOMnSEPzN66SL8Mh-f2pPWBDeWaKbXTPUIdrZph7yj8Z93Rl8uZ16m7Qjz-E-9JFKSsJ-F=s128 148 | [balance] => 1 149 | [public_key] => 17z1Rq3VsyvvXvGWiHT8YErjBoFgnhErB8 150 | [account_name] => 151 | [account_tag] => 152 | [price_btc] => 0.00019038 153 | [price_usd] => 1.00036293 154 | [change_btc] => 0.013486479778200063 155 | [change_usd] => 0.005376748815937048 156 | [asset_key] => 815b0b1a-2764-3736-8faa-42d694fa620a 157 | [confirmations] => 6 158 | [capitalization] => 0 159 | ) 160 | Array 161 | ( 162 | [type] => transfer 163 | [snapshot_id] => f4b1f8d6-004a-4d2b-997d-4d0acf1096cd 164 | [opponent_id] => aaff5bef-42fb-4c9f-90e0-29f69176b7d4 165 | [asset_id] => 815b0b1a-2764-3736-8faa-42d694fa620a 166 | [amount] => -1 167 | [trace_id] => b12eed67-6cf4-481f-b25b-dd41f28e1984 168 | [memo] => hKFToUKhQcQQyUrIj0ZxOXa2CgkGTxgR6KFQozExMqFUoUw= 169 | [created_at] => 2019-04-30T01:17:02.206240549Z 170 | [counter_user_id] => aaff5bef-42fb-4c9f-90e0-29f69176b7d4 171 | ) 172 | The Order ID (trace_id) is: b12eed67-6cf4-481f-b25b-dd41f28e1984 173 | ``` 174 | ## Batalkan Pesanan 175 | Untuk membatalkan pesanan, cukup bayar jumlah aset apa pun ke OceanOne, dan tulis trace_id ke memo. Ocean.one menggunakan trace_id sebagai id pesanan, misalnya, **b12eed67-6cf4-481f-b25b-dd41f28e1984** adalah id pesanan, 176 | Kita bisa menggunakannya untuk membatalkan pesanan. 177 | 178 | ```php 179 | if ( $ocmd == 'c' ) { 180 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 181 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(CNB_ASSET_ID); 182 | if ( ((float) $asset_info["balance"] == 0) ) { 183 | echo "Please deposit some CNB to this Wallet!" . PHP_EOL; 184 | } else { 185 | $orderid = readline("Input the Order id ( trace_id ): "); 186 | $cMemo = base64_encode(MessagePack::pack([ 187 | 'O' => Uuid::fromString($orderid)->getBytes(), 188 | ])); 189 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(CNB_ASSET_ID,OCEANONE_BOT, 190 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 191 | "0.00000001", 192 | $cMemo); 193 | print_r($transInfos); 194 | } 195 | } 196 | ``` 197 | #### Lihat saldo Bitcoin 198 | Periksa saldo dompet. 199 | ```php 200 | if ($line == 'aw') { 201 | $mixinSdk_eachAccountInstance = GenerateWalletSDKFromCSV(); 202 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAssets(); 203 | foreach ($asset_info as $key => $asset) { 204 | echo $asset["symbol"] . " " . $asset["asset_id"] ." ". $asset["balance"] . 205 | " ". $asset["public_key"].PHP_EOL; 206 | } 207 | } 208 | ``` 209 | 210 | ## Penggunaan kode sumber 211 | Bangun dan jalankan. 212 | 213 | - **php bitcoin_wallet.php** jalankan itu. 214 | 215 | Perintah perdagangan dengan OceanOne: 216 | 217 | - o: Pertukaran Ocean.One 218 | - q: Keluar 219 | 220 | Tentukan pilihan Anda (mis: q untuk Keluar!): 221 | 222 | - 1: Ambil pesanan XIN/USDT 223 | - s1: Jual XIN/USDT 224 | - b1: Beli/USDT 225 | - 2: Ambil pesanan ERC20 (Benz) / USDT 226 | - s2: Jual Benz/USDT 227 | - b2: Beli Benz/USDT 228 | - q: Keluar 229 | 230 | [Kode lengkap disini](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/bitcoin_wallet.php) 231 | 232 | -------------------------------------------------------------------------------- /README-japanese-lang.md: -------------------------------------------------------------------------------- 1 | # Mixin Messenger ロボットプログラム作成教程【PHP編】 2 | -------------------------------------------------------------------------------- /README-spanish.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README2-russian.md: -------------------------------------------------------------------------------- 1 | # Туториал по PHP для работы с биткойном через Mixin Network, часть II: Получайте и отправляйте Bitcoin в Mixin Messenger 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | В [предыдущей главе](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README-russian.md) ваш первый бот начал работать. Это echo-бот, он возвращал сообщения. 5 | 6 | Создайте файл app.php с таким кодом: 7 | ```php 8 | 15 18 | ]); 19 | class callTraitClass { 20 | use MixinSDKTrait; 21 | public $config; 22 | public function __construct() 23 | { 24 | $config = require(__DIR__.'/config.php'); 25 | $this->config = $config; 26 | } 27 | } 28 | $callTrait = new callTraitClass(); 29 | $Token = $callTrait->getToken('GET', '/', ''); 30 | print_r($callTrait->config['client_id']); 31 | // $Header = 'Authorization'.'Bearer '.$Token; 32 | // print($Header); 33 | $connector = new \Ratchet\Client\Connector($loop,$reactConnector); 34 | // $connector('ws://127.0.0.1:9000', ['protocol' => 'Mixin-Blaze-1'], ['Origin' => 'http://localhost', 35 | $connector('wss://blaze.mixin.one', ['protocol' => 'Mixin-Blaze-1'],[ 36 | 'Authorization' => 'Bearer '.$Token 37 | ]) 38 | ->then(function(Ratchet\Client\WebSocket $conn) { 39 | $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) { 40 | $jsMsg = json_decode(gzdecode($msg)); 41 | print_r($jsMsg); 42 | if ($jsMsg->action === 'CREATE_MESSAGE' and property_exists($jsMsg,'data')) { 43 | echo "\nNeed reply server a receipt!\n"; 44 | $RspMsg = generateReceipt($jsMsg->data->message_id); 45 | $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY); 46 | $conn->send($msg); 47 | 48 | if ($jsMsg->data->category === 'PLAIN_TEXT') { 49 | echo "PLAIN_TEXT:".base64_decode($jsMsg->data->data); 50 | $isCmd = strtolower(base64_decode($jsMsg->data->data)); 51 | if ($isCmd ==='?' or $isCmd ==='help') { 52 | $msgData = sendUsage($jsMsg->data->conversation_id); 53 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 54 | $conn->send($msg); 55 | } elseif ($isCmd === '1') { 56 | // print($callTrait->config['client_id']); 57 | $msgData = sendAppButtons($jsMsg); 58 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 59 | $conn->send($msg); 60 | }//end of pay1 61 | 62 | elseif ($isCmd === '2') { 63 | // print($callTrait->config['client_id']); 64 | $msgData = sendAppCard($jsMsg); 65 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 66 | $conn->send($msg); 67 | }//end of pay2 68 | elseif ($isCmd === '3') { 69 | transfer(); 70 | } else { 71 | $msgData = sendPlainText($jsMsg->data->conversation_id, 72 | base64_decode($jsMsg->data->data)); 73 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 74 | $conn->send($msg); 75 | } 76 | } //end of PLAIN_TEXT 77 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 78 | // refundInstant 79 | echo "user id:".$jsMsg->data->user_id; 80 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 81 | print_r($dtPay); 82 | if ($dtPay->amount > 0) { 83 | echo "paid!".$dtPay->asset_id; 84 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 85 | } 86 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 87 | } //end of CREATE_MESSAGE 88 | 89 | }); 90 | 91 | $conn->on('close', function($code = null, $reason = null) { 92 | echo "Connection closed ({$code} - {$reason})\n"; 93 | }); 94 | /* start listen for the incoming message */ 95 | $message = [ 96 | 'id' => Uuid::uuid4()->toString(), 97 | 'action' => 'LIST_PENDING_MESSAGES', 98 | ]; 99 | print_r(json_encode($message)); 100 | $msg = new Frame(gzencode(json_encode($message)),true,Frame::OP_BINARY); 101 | $conn->send($msg); 102 | // $conn->send(gzencode($msg,1,FORCE_DEFLATE)); 103 | }, function(\Exception $e) use ($loop) { 104 | echo "Could not connect: {$e->getMessage()}\n"; 105 | $loop->stop(); 106 | }); 107 | 108 | $loop->run(); 109 | 110 | 111 | function sendUsage($conversation_id):Array { 112 | $msgHelp = << $conversation_id, 125 | 'category' => 'PLAIN_TEXT', 126 | 'status' => 'SENT', 127 | 'message_id' => Uuid::uuid4()->toString(), 128 | 'data' => base64_encode($msgContent),//base64_encode("hello!"), 129 | ]; 130 | $msgPayButton = [ 131 | 'id' => Uuid::uuid4()->toString(), 132 | 'action' => 'CREATE_MESSAGE', 133 | 'params' => $msgParams, 134 | ]; 135 | return $msgPayButton; 136 | } 137 | function sendAppButtons($jsMsg):Array { 138 | $payLinkEOS = "https://mixin.one/pay?recipient=". 139 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 140 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 141 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 142 | "&memo="; 143 | $payLinkBTC = "https://mixin.one/pay?recipient=". 144 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 145 | "c6d0c728-2624-429b-8e0d-d9d19b6592fa". 146 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 147 | "&memo="; 148 | $msgData = [[ 149 | 'label' => "Pay 0.001 EOS", 150 | 'color' => "#FFABAB", 151 | 'action' => $payLinkEOS, 152 | ],[ 153 | 'label' => "Pay 0.0001 BTC", 154 | 'color' => "#00EEFF", 155 | 'action' => $payLinkBTC, 156 | ], 157 | ]; 158 | $msgParams = [ 159 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 160 | // 'recipient_id' => $jsMsg->data->user_id, 161 | 'category' => 'APP_BUTTON_GROUP',//'PLAIN_TEXT', 162 | 'status' => 'SENT', 163 | 'message_id' => Uuid::uuid4()->toString(), 164 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 165 | ]; 166 | $msgPayButtons = [ 167 | 'id' => Uuid::uuid4()->toString(), 168 | 'action' => 'CREATE_MESSAGE', 169 | 'params' => $msgParams, 170 | ]; 171 | return $msgPayButtons; 172 | } 173 | 174 | function sendAppCard($jsMsg):Array 175 | { 176 | $payLink = "https://mixin.one/pay?recipient=". 177 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 178 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 179 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 180 | "&memo="; 181 | $msgData = [ 182 | 'icon_url' => "https://mixin.one/assets/98b586edb270556d1972112bd7985e9e.png", 183 | 'title' => "Pay 0.001 EOS", 184 | 'description' => "pay", 185 | 'action' => $payLink, 186 | ]; 187 | $msgParams = [ 188 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 189 | // 'recipient_id' => $jsMsg->data->user_id, 190 | 'category' => 'APP_CARD',//'PLAIN_TEXT', 191 | 'status' => 'SENT', 192 | 'message_id' => Uuid::uuid4()->toString(), 193 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 194 | ]; 195 | $msgPayButton = [ 196 | 'id' => Uuid::uuid4()->toString(), 197 | 'action' => 'CREATE_MESSAGE', 198 | 'params' => $msgParams, 199 | ]; 200 | return $msgPayButton; 201 | } 202 | 203 | function transfer() { 204 | $mixinSdk = new MixinSDK(require './config.php'); 205 | print_r($mixinSdk->getConfig()); 206 | } 207 | 208 | function generateReceipt($msgID):Array { 209 | $IncomingMsg = ["message_id" => $msgID, "status" => "READ"]; 210 | $RspMsg = ["id" => Uuid::uuid4()->toString(), "action" => "ACKNOWLEDGE_MESSAGE_RECEIPT", 211 | "params" => $IncomingMsg]; 212 | return $RspMsg; 213 | } 214 | function refundInstant($_assetID,$_amount,$_opponent_id) { 215 | $mixinSdk = new MixinSDK(require './config.php'); 216 | // print_r(); 217 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 218 | $mixinSdk->getConfig()['default']['pin'],$_amount); 219 | print_r($BotInfo); 220 | } 221 | ``` 222 | ### Начало работы с биткойном 223 | Запустите **php app.php** в проектной папке. 224 | 225 | ```bash 226 | php app.php 227 | ``` 228 | 229 | ```bash 230 | wenewzha:mixin_labs-php-bot wenewzhang$ php app.php 231 | a1ce2967-a534-417d-bf12-c86571e4eefa{"id":"12c7a470-d6a4-403d-94e8-e6f8ae833971","action":"LIST_PENDING_MESSAGES"}stdClass Object 232 | ( 233 | [id] => 12c7a470-d6a4-403d-94e8-e6f8ae833971 234 | [action] => LIST_PENDING_MESSAGES 235 | ) 236 | ``` 237 | Бот успешно подключен к mixin.one, если консоль выводит "LIST_PENDING_MESSAGES". 238 | 239 | ![pay-links](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/pay-links.jpg) 240 | 241 | Бот рассказывает, как с ним взаимодействовать: 242 | - Наберите **1** для отправки ссылки APP_CARD; 243 | - Наберите **2** для отправки ссылки APP_BUTTON_GROUP; 244 | - Наберите **? или help** для получения помощи. 245 | Выберите нужную кнопку в окне сообщений, введите ПИН-код, и бот получит оплату. 246 | ![click-pay-link-to-pay](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/click-link-to-pay.jpg) 247 | 248 | Всё [о сообщениях в Mixin Messenger](https://developers.mixin.one/api/beta-mixin-message/websocket-messages/). 249 | 250 | Вы можете заплатить боту 0.001 биткойн, и 0.001 биткойн будет возвращен в течение 1 секунды. Оплата может быть в любой криптовалюте. 251 | ![pay-link](https://github.com/wenewzhang/mixin_network-nodejs-bot2/raw/master/Pay_and_refund_quickly.jpg) 252 | 253 | Разработчики могут отправлять биткойны своим ботам на странице чата. Бот получает биткойн и сразу же возвращает. 254 | ![transfer Bitcoin](https://github.com/wenewzhang/mixin_network-nodejs-bot2/raw/master/transfer-any-tokens.jpg) 255 | 256 | ## Краткое описание исходного кода 257 | ```php 258 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 259 | $conn->send($msg); 260 | ``` 261 | При отправке сообщений пользователю используется json для сериализации и gzencode для сжатия. 262 | 263 | ```php 264 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 265 | // refundInstant 266 | echo "user id:".$jsMsg->data->user_id; 267 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 268 | print_r($dtPay); 269 | if ($dtPay->amount > 0) { 270 | echo "paid!".$dtPay->asset_id; 271 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 272 | } 273 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 274 | ``` 275 | 276 | – Если бот отправил биткойн пользователю, то сумма $dtPay->amount отрицательна. 277 | – Если бот получает биткойн от пользователя, то сумма $dtPay->amount положительна. 278 | 279 | Биткойн переводится пользователю с помощью следующего кода: 280 | ```php 281 | function refundInstant($_assetID,$_amount,$_opponent_id) { 282 | $mixinSdk = new MixinSDK(require './config.php'); 283 | // print_r(); 284 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 285 | $mixinSdk->getConfig()['default']['pin'],$_amount); 286 | print_r($BotInfo); 287 | } 288 | 289 | ``` 290 | 291 | 292 | Полное описание кода [здесь](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/app.php) 293 | -------------------------------------------------------------------------------- /README2-spanish.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README2-zhchs.md: -------------------------------------------------------------------------------- 1 | 2 | # 基于Mixin Network的PHP比特币开发教程: 机器人接受比特币并立即退还用户 3 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 4 | 5 | 在 [上一篇教程中](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README-zhchs.md), 我们创建了自动回复消息的机器人,当用户发送消息"Hello,World!"时,机器人会自动回复同一条消息! 6 | 7 | 8 | 按本篇教程后学习后完成后,你的机器人将会接受用户发送过来的加密货币,然后立即转回用户。下面是全部源代码,创建一个app.php试一下吧! 9 | 10 | ```php 11 | 15 21 | ]); 22 | class callTraitClass { 23 | use MixinSDKTrait; 24 | public $config; 25 | public function __construct() 26 | { 27 | $config = require(__DIR__.'/config.php'); 28 | $this->config = $config; 29 | } 30 | } 31 | $callTrait = new callTraitClass(); 32 | $Token = $callTrait->getToken('GET', '/', ''); 33 | print_r($callTrait->config['client_id']); 34 | // $Header = 'Authorization'.'Bearer '.$Token; 35 | // print($Header); 36 | $connector = new \Ratchet\Client\Connector($loop,$reactConnector); 37 | // $connector('ws://127.0.0.1:9000', ['protocol' => 'Mixin-Blaze-1'], ['Origin' => 'http://localhost', 38 | $connector('wss://blaze.mixin.one', ['protocol' => 'Mixin-Blaze-1'],[ 39 | 'Authorization' => 'Bearer '.$Token 40 | ]) 41 | ->then(function(Ratchet\Client\WebSocket $conn) { 42 | $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) { 43 | $jsMsg = json_decode(gzdecode($msg)); 44 | print_r($jsMsg); 45 | if ($jsMsg->action === 'CREATE_MESSAGE' and property_exists($jsMsg,'data')) { 46 | echo "\nNeed reply server a receipt!\n"; 47 | $RspMsg = generateReceipt($jsMsg->data->message_id); 48 | $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY); 49 | $conn->send($msg); 50 | 51 | if ($jsMsg->data->category === 'PLAIN_TEXT') { 52 | echo "PLAIN_TEXT:".base64_decode($jsMsg->data->data); 53 | $isCmd = strtolower(base64_decode($jsMsg->data->data)); 54 | if ($isCmd ==='?' or $isCmd ==='help') { 55 | $msgData = sendUsage($jsMsg->data->conversation_id); 56 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 57 | $conn->send($msg); 58 | } elseif ($isCmd === '1') { 59 | // print($callTrait->config['client_id']); 60 | $msgData = sendAppButtons($jsMsg); 61 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 62 | $conn->send($msg); 63 | }//end of pay1 64 | 65 | elseif ($isCmd === '2') { 66 | // print($callTrait->config['client_id']); 67 | $msgData = sendAppCard($jsMsg); 68 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 69 | $conn->send($msg); 70 | }//end of pay2 71 | elseif ($isCmd === '3') { 72 | transfer(); 73 | } else { 74 | $msgData = sendPlainText($jsMsg->data->conversation_id, 75 | base64_decode($jsMsg->data->data)); 76 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 77 | $conn->send($msg); 78 | } 79 | } //end of PLAIN_TEXT 80 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 81 | // refundInstant 82 | echo "user id:".$jsMsg->data->user_id; 83 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 84 | print_r($dtPay); 85 | if ($dtPay->amount > 0) { 86 | echo "paid!".$dtPay->asset_id; 87 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 88 | } 89 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 90 | } //end of CREATE_MESSAGE 91 | 92 | }); 93 | 94 | $conn->on('close', function($code = null, $reason = null) { 95 | echo "Connection closed ({$code} - {$reason})\n"; 96 | }); 97 | /* start listen for the incoming message */ 98 | $message = [ 99 | 'id' => Uuid::uuid4()->toString(), 100 | 'action' => 'LIST_PENDING_MESSAGES', 101 | ]; 102 | print_r(json_encode($message)); 103 | $msg = new Frame(gzencode(json_encode($message)),true,Frame::OP_BINARY); 104 | $conn->send($msg); 105 | // $conn->send(gzencode($msg,1,FORCE_DEFLATE)); 106 | }, function(\Exception $e) use ($loop) { 107 | echo "Could not connect: {$e->getMessage()}\n"; 108 | $loop->stop(); 109 | }); 110 | 111 | $loop->run(); 112 | 113 | 114 | function sendUsage($conversation_id):Array { 115 | $msgHelp = << $conversation_id, 128 | 'category' => 'PLAIN_TEXT', 129 | 'status' => 'SENT', 130 | 'message_id' => Uuid::uuid4()->toString(), 131 | 'data' => base64_encode($msgContent),//base64_encode("hello!"), 132 | ]; 133 | $msgPayButton = [ 134 | 'id' => Uuid::uuid4()->toString(), 135 | 'action' => 'CREATE_MESSAGE', 136 | 'params' => $msgParams, 137 | ]; 138 | return $msgPayButton; 139 | } 140 | function sendAppButtons($jsMsg):Array { 141 | $payLinkEOS = "https://mixin.one/pay?recipient=". 142 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 143 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 144 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 145 | "&memo="; 146 | $payLinkBTC = "https://mixin.one/pay?recipient=". 147 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 148 | "c6d0c728-2624-429b-8e0d-d9d19b6592fa". 149 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 150 | "&memo="; 151 | $msgData = [[ 152 | 'label' => "Pay 0.001 EOS", 153 | 'color' => "#FFABAB", 154 | 'action' => $payLinkEOS, 155 | ],[ 156 | 'label' => "Pay 0.0001 BTC", 157 | 'color' => "#00EEFF", 158 | 'action' => $payLinkBTC, 159 | ], 160 | ]; 161 | $msgParams = [ 162 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 163 | // 'recipient_id' => $jsMsg->data->user_id, 164 | 'category' => 'APP_BUTTON_GROUP',//'PLAIN_TEXT', 165 | 'status' => 'SENT', 166 | 'message_id' => Uuid::uuid4()->toString(), 167 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 168 | ]; 169 | $msgPayButtons = [ 170 | 'id' => Uuid::uuid4()->toString(), 171 | 'action' => 'CREATE_MESSAGE', 172 | 'params' => $msgParams, 173 | ]; 174 | return $msgPayButtons; 175 | } 176 | 177 | function sendAppCard($jsMsg):Array 178 | { 179 | $payLink = "https://mixin.one/pay?recipient=". 180 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 181 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 182 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 183 | "&memo="; 184 | $msgData = [ 185 | 'icon_url' => "https://mixin.one/assets/98b586edb270556d1972112bd7985e9e.png", 186 | 'title' => "Pay 0.001 EOS", 187 | 'description' => "pay", 188 | 'action' => $payLink, 189 | ]; 190 | $msgParams = [ 191 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 192 | // 'recipient_id' => $jsMsg->data->user_id, 193 | 'category' => 'APP_CARD',//'PLAIN_TEXT', 194 | 'status' => 'SENT', 195 | 'message_id' => Uuid::uuid4()->toString(), 196 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 197 | ]; 198 | $msgPayButton = [ 199 | 'id' => Uuid::uuid4()->toString(), 200 | 'action' => 'CREATE_MESSAGE', 201 | 'params' => $msgParams, 202 | ]; 203 | return $msgPayButton; 204 | } 205 | 206 | function transfer() { 207 | $mixinSdk = new MixinSDK(require './config.php'); 208 | print_r($mixinSdk->getConfig()); 209 | } 210 | 211 | function generateReceipt($msgID):Array { 212 | $IncomingMsg = ["message_id" => $msgID, "status" => "READ"]; 213 | $RspMsg = ["id" => Uuid::uuid4()->toString(), "action" => "ACKNOWLEDGE_MESSAGE_RECEIPT", 214 | "params" => $IncomingMsg]; 215 | return $RspMsg; 216 | } 217 | function refundInstant($_assetID,$_amount,$_opponent_id) { 218 | $mixinSdk = new MixinSDK(require './config.php'); 219 | // print_r(); 220 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 221 | $mixinSdk->getConfig()['default']['pin'],$_amount); 222 | print_r($BotInfo); 223 | } 224 | ``` 225 | ### 你好,我的币! 226 | 在工程目录下,执行 **php app.php** 227 | 228 | ```bash 229 | php app.php 230 | ``` 231 | 232 | ```bash 233 | wenewzha:mixin_labs-php-bot wenewzhang$ php app.php 234 | a1ce2967-a534-417d-bf12-c86571e4eefa{"id":"12c7a470-d6a4-403d-94e8-e6f8ae833971","action":"LIST_PENDING_MESSAGES"}stdClass Object 235 | ( 236 | [id] => 12c7a470-d6a4-403d-94e8-e6f8ae833971 237 | [action] => LIST_PENDING_MESSAGES 238 | ) 239 | ``` 240 | 如果控制台出现 "LIST_PENDING_MESSAGES"字样, 连接到mixin.one成功了,正在侦听用户发送消息给它! 241 | 242 | ![pay-links](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/pay-links.jpg) 243 | 244 | 按帮助来操作,发送消息得到相应的支付提示 245 | - **1** 机器人回复 APP_CARD 支付链接. 246 | - **2** 机器人回复 APP_BUTTON_GROUP 支付链接. 247 | - **? or help** : 显示帮助 248 | 点击上面的链接,将会弹出一个窗口,输入你的密码,将支付币给机器人! 249 | ![click-pay-link-to-pay](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/click-link-to-pay.jpg) 250 | 251 | [Mixin Messenger支持的消息类型](https://developers.mixin.one/api/beta-mixin-message/websocket-messages/) 252 | 253 | 如下图所示,用户点击支付链接,输入密码,支付0.01 EOS给机器人,机器人马上返还给用户! 254 | ![pay-link](https://github.com/myrual/mixin_network-nodejs-bot2/raw/master/Pay_and_refund_quickly.jpg) 255 | 256 | 亲爱的开发者,你也可以从消息控制面板里,点击转帐,直接将币转给机器人!它还是一样的立即返还! 257 | ![transfer and tokens](https://github.com/wenewzhang/mixin_network-nodejs-bot2/raw/master/transfer-any-tokens.jpg) 258 | 259 | ## 源代码解释 260 | ```php 261 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 262 | $conn->send($msg); 263 | ``` 264 | 机器人发送给用户的消息,先用json序列化,再用gzencode压缩。 265 | 266 | ```php 267 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 268 | // refundInstant 269 | echo "user id:".$jsMsg->data->user_id; 270 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 271 | print_r($dtPay); 272 | if ($dtPay->amount > 0) { 273 | echo "paid!".$dtPay->asset_id; 274 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 275 | } 276 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 277 | ``` 278 | 如果机器人收到币, 279 | ```php 280 | $dtPay->amount 281 | ``` 282 | 大于零;如果机器人支付币给用户,接收到的消息是一样的,唯一不同的是 283 | ```php 284 | $dtPay->amount 285 | ``` 286 | 是一个负数. 287 | 288 | ```php 289 | function refundInstant($_assetID,$_amount,$_opponent_id) { 290 | $mixinSdk = new MixinSDK(require './config.php'); 291 | // print_r(); 292 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 293 | $mixinSdk->getConfig()['default']['pin'],$_amount); 294 | print_r($BotInfo); 295 | } 296 | 297 | ``` 298 | 最后一步,调用MixinSDK将币还给用户! 299 | 300 | 完整的代码在这儿 [here](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/app.php) 301 | -------------------------------------------------------------------------------- /README2.md: -------------------------------------------------------------------------------- 1 | # PHP Bitcoin tutorial based on Mixin Network II: Receive and send Bitcoin in Mixin Messenger 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | In [the previous chapter](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README.md), your first bot just work. The bot echo message from user. 5 | 6 | Create an app.php file with following code: 7 | ```php 8 | 15 18 | ]); 19 | class callTraitClass { 20 | use MixinSDKTrait; 21 | public $config; 22 | public function __construct() 23 | { 24 | $config = require(__DIR__.'/config.php'); 25 | $this->config = $config; 26 | } 27 | } 28 | $callTrait = new callTraitClass(); 29 | $Token = $callTrait->getToken('GET', '/', ''); 30 | print_r($callTrait->config['client_id']); 31 | // $Header = 'Authorization'.'Bearer '.$Token; 32 | // print($Header); 33 | $connector = new \Ratchet\Client\Connector($loop,$reactConnector); 34 | // $connector('ws://127.0.0.1:9000', ['protocol' => 'Mixin-Blaze-1'], ['Origin' => 'http://localhost', 35 | $connector('wss://blaze.mixin.one', ['protocol' => 'Mixin-Blaze-1'],[ 36 | 'Authorization' => 'Bearer '.$Token 37 | ]) 38 | ->then(function(Ratchet\Client\WebSocket $conn) { 39 | $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) { 40 | $jsMsg = json_decode(gzdecode($msg)); 41 | print_r($jsMsg); 42 | if ($jsMsg->action === 'CREATE_MESSAGE' and property_exists($jsMsg,'data')) { 43 | echo "\nNeed reply server a receipt!\n"; 44 | $RspMsg = generateReceipt($jsMsg->data->message_id); 45 | $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY); 46 | $conn->send($msg); 47 | 48 | if ($jsMsg->data->category === 'PLAIN_TEXT') { 49 | echo "PLAIN_TEXT:".base64_decode($jsMsg->data->data); 50 | $isCmd = strtolower(base64_decode($jsMsg->data->data)); 51 | if ($isCmd ==='?' or $isCmd ==='help') { 52 | $msgData = sendUsage($jsMsg->data->conversation_id); 53 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 54 | $conn->send($msg); 55 | } elseif ($isCmd === '1') { 56 | // print($callTrait->config['client_id']); 57 | $msgData = sendAppButtons($jsMsg); 58 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 59 | $conn->send($msg); 60 | }//end of pay1 61 | 62 | elseif ($isCmd === '2') { 63 | // print($callTrait->config['client_id']); 64 | $msgData = sendAppCard($jsMsg); 65 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 66 | $conn->send($msg); 67 | }//end of pay2 68 | elseif ($isCmd === '3') { 69 | transfer(); 70 | } else { 71 | $msgData = sendPlainText($jsMsg->data->conversation_id, 72 | base64_decode($jsMsg->data->data)); 73 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 74 | $conn->send($msg); 75 | } 76 | } //end of PLAIN_TEXT 77 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 78 | // refundInstant 79 | echo "user id:".$jsMsg->data->user_id; 80 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 81 | print_r($dtPay); 82 | if ($dtPay->amount > 0) { 83 | echo "paid!".$dtPay->asset_id; 84 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 85 | } 86 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 87 | } //end of CREATE_MESSAGE 88 | 89 | }); 90 | 91 | $conn->on('close', function($code = null, $reason = null) { 92 | echo "Connection closed ({$code} - {$reason})\n"; 93 | }); 94 | /* start listen for the incoming message */ 95 | $message = [ 96 | 'id' => Uuid::uuid4()->toString(), 97 | 'action' => 'LIST_PENDING_MESSAGES', 98 | ]; 99 | print_r(json_encode($message)); 100 | $msg = new Frame(gzencode(json_encode($message)),true,Frame::OP_BINARY); 101 | $conn->send($msg); 102 | // $conn->send(gzencode($msg,1,FORCE_DEFLATE)); 103 | }, function(\Exception $e) use ($loop) { 104 | echo "Could not connect: {$e->getMessage()}\n"; 105 | $loop->stop(); 106 | }); 107 | 108 | $loop->run(); 109 | 110 | 111 | function sendUsage($conversation_id):Array { 112 | $msgHelp = << $conversation_id, 125 | 'category' => 'PLAIN_TEXT', 126 | 'status' => 'SENT', 127 | 'message_id' => Uuid::uuid4()->toString(), 128 | 'data' => base64_encode($msgContent),//base64_encode("hello!"), 129 | ]; 130 | $msgPayButton = [ 131 | 'id' => Uuid::uuid4()->toString(), 132 | 'action' => 'CREATE_MESSAGE', 133 | 'params' => $msgParams, 134 | ]; 135 | return $msgPayButton; 136 | } 137 | function sendAppButtons($jsMsg):Array { 138 | $payLinkEOS = "https://mixin.one/pay?recipient=". 139 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 140 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 141 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 142 | "&memo="; 143 | $payLinkBTC = "https://mixin.one/pay?recipient=". 144 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 145 | "c6d0c728-2624-429b-8e0d-d9d19b6592fa". 146 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 147 | "&memo="; 148 | $msgData = [[ 149 | 'label' => "Pay 0.001 EOS", 150 | 'color' => "#FFABAB", 151 | 'action' => $payLinkEOS, 152 | ],[ 153 | 'label' => "Pay 0.0001 BTC", 154 | 'color' => "#00EEFF", 155 | 'action' => $payLinkBTC, 156 | ], 157 | ]; 158 | $msgParams = [ 159 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 160 | // 'recipient_id' => $jsMsg->data->user_id, 161 | 'category' => 'APP_BUTTON_GROUP',//'PLAIN_TEXT', 162 | 'status' => 'SENT', 163 | 'message_id' => Uuid::uuid4()->toString(), 164 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 165 | ]; 166 | $msgPayButtons = [ 167 | 'id' => Uuid::uuid4()->toString(), 168 | 'action' => 'CREATE_MESSAGE', 169 | 'params' => $msgParams, 170 | ]; 171 | return $msgPayButtons; 172 | } 173 | 174 | function sendAppCard($jsMsg):Array 175 | { 176 | $payLink = "https://mixin.one/pay?recipient=". 177 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 178 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 179 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 180 | "&memo="; 181 | $msgData = [ 182 | 'icon_url' => "https://mixin.one/assets/98b586edb270556d1972112bd7985e9e.png", 183 | 'title' => "Pay 0.001 EOS", 184 | 'description' => "pay", 185 | 'action' => $payLink, 186 | ]; 187 | $msgParams = [ 188 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 189 | // 'recipient_id' => $jsMsg->data->user_id, 190 | 'category' => 'APP_CARD',//'PLAIN_TEXT', 191 | 'status' => 'SENT', 192 | 'message_id' => Uuid::uuid4()->toString(), 193 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 194 | ]; 195 | $msgPayButton = [ 196 | 'id' => Uuid::uuid4()->toString(), 197 | 'action' => 'CREATE_MESSAGE', 198 | 'params' => $msgParams, 199 | ]; 200 | return $msgPayButton; 201 | } 202 | 203 | function transfer() { 204 | $mixinSdk = new MixinSDK(require './config.php'); 205 | print_r($mixinSdk->getConfig()); 206 | } 207 | 208 | function generateReceipt($msgID):Array { 209 | $IncomingMsg = ["message_id" => $msgID, "status" => "READ"]; 210 | $RspMsg = ["id" => Uuid::uuid4()->toString(), "action" => "ACKNOWLEDGE_MESSAGE_RECEIPT", 211 | "params" => $IncomingMsg]; 212 | return $RspMsg; 213 | } 214 | function refundInstant($_assetID,$_amount,$_opponent_id) { 215 | $mixinSdk = new MixinSDK(require './config.php'); 216 | // print_r(); 217 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 218 | $mixinSdk->getConfig()['default']['pin'],$_amount); 219 | print_r($BotInfo); 220 | } 221 | ``` 222 | ### Hello Bitcoin 223 | Run **php app.php** in the project directory. 224 | 225 | ```bash 226 | php app.php 227 | ``` 228 | 229 | ```bash 230 | wenewzha:mixin_labs-php-bot wenewzhang$ php app.php 231 | a1ce2967-a534-417d-bf12-c86571e4eefa{"id":"12c7a470-d6a4-403d-94e8-e6f8ae833971","action":"LIST_PENDING_MESSAGES"}stdClass Object 232 | ( 233 | [id] => 12c7a470-d6a4-403d-94e8-e6f8ae833971 234 | [action] => LIST_PENDING_MESSAGES 235 | ) 236 | ``` 237 | The bot connect to the mixin.one successfully when console output "LIST_PENDING_MESSAGES". 238 | 239 | ![pay-links](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/pay-links.jpg) 240 | 241 | The bot has told you how to interact: 242 | - **1** the bot send an APP_CARD link. 243 | - **2** the bot send an APP_BUTTON_GROUP link. 244 | - **? or help** for help! 245 | Click the links in chatting page, input PIN code to pay coin to bot. 246 | ![click-pay-link-to-pay](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/click-link-to-pay.jpg) 247 | 248 | Full [Mixin Messenger messages introduction](https://developers.mixin.one/api/beta-mixin-message/websocket-messages/). 249 | 250 | User can pay 0.001 Bitcoin to bot, the 0.001 Bitcoin will be refunded in 1 seconds. In fact, user can pay any coins. 251 | ![pay-link](https://github.com/wenewzhang/mixin_network-nodejs-bot2/raw/master/Pay_and_refund_quickly.jpg) 252 | 253 | Developer can send Bitcoin to their bots in chatting page. The bot will send back immediately after received Bitcoin. 254 | ![transfer Bitcoin](https://github.com/wenewzhang/mixin_network-nodejs-bot2/raw/master/transfer-any-tokens.jpg) 255 | 256 | ## Source code summary 257 | ```php 258 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 259 | $conn->send($msg); 260 | ``` 261 | The bot send messages to user, Which use json serialize and then use gzencode compress it. 262 | 263 | ```php 264 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 265 | // refundInstant 266 | echo "user id:".$jsMsg->data->user_id; 267 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 268 | print_r($dtPay); 269 | if ($dtPay->amount > 0) { 270 | echo "paid!".$dtPay->asset_id; 271 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 272 | } 273 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 274 | ``` 275 | 276 | * The $dtPay->amount is negative if bot sends Bitcoin to user successfully. 277 | * The $dtPay->amount is positive if bot receives Bitcoin. 278 | 279 | Following code transfer the Bitcoin to user. 280 | ```php 281 | function refundInstant($_assetID,$_amount,$_opponent_id) { 282 | $mixinSdk = new MixinSDK(require './config.php'); 283 | // print_r(); 284 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 285 | $mixinSdk->getConfig()['default']['pin'],$_amount); 286 | print_r($BotInfo); 287 | } 288 | 289 | ``` 290 | 291 | 292 | Full code is [here](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/app.php) 293 | -------------------------------------------------------------------------------- /README2_Brazilian_Portuguese.md: -------------------------------------------------------------------------------- 1 | # PHP Bitcoin tutorial baseado na Mixin Network II: Receba e envie Bitcoin no Mixin Messenger 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | No [cápitulo anterior](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README_Brazilian_Portuguese.md), seu primeiro bot acabou de funcionar. O bot ecoa mensagem do usuário. 5 | 6 | Crie um arquivo app.php com o seguinte código: 7 | ```php 8 | 15 18 | ]); 19 | class callTraitClass { 20 | use MixinSDKTrait; 21 | public $config; 22 | public function __construct() 23 | { 24 | $config = require(__DIR__.'/config.php'); 25 | $this->config = $config; 26 | } 27 | } 28 | $callTrait = new callTraitClass(); 29 | $Token = $callTrait->getToken('GET', '/', ''); 30 | print_r($callTrait->config['client_id']); 31 | // $Header = 'Authorization'.'Bearer '.$Token; 32 | // print($Header); 33 | $connector = new \Ratchet\Client\Connector($loop,$reactConnector); 34 | // $connector('ws://127.0.0.1:9000', ['protocol' => 'Mixin-Blaze-1'], ['Origin' => 'http://localhost', 35 | $connector('wss://blaze.mixin.one', ['protocol' => 'Mixin-Blaze-1'],[ 36 | 'Authorization' => 'Bearer '.$Token 37 | ]) 38 | ->then(function(Ratchet\Client\WebSocket $conn) { 39 | $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) { 40 | $jsMsg = json_decode(gzdecode($msg)); 41 | print_r($jsMsg); 42 | if ($jsMsg->action === 'CREATE_MESSAGE' and property_exists($jsMsg,'data')) { 43 | echo "\nNeed reply server a receipt!\n"; 44 | $RspMsg = generateReceipt($jsMsg->data->message_id); 45 | $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY); 46 | $conn->send($msg); 47 | 48 | if ($jsMsg->data->category === 'PLAIN_TEXT') { 49 | echo "PLAIN_TEXT:".base64_decode($jsMsg->data->data); 50 | $isCmd = strtolower(base64_decode($jsMsg->data->data)); 51 | if ($isCmd ==='?' or $isCmd ==='help') { 52 | $msgData = sendUsage($jsMsg->data->conversation_id); 53 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 54 | $conn->send($msg); 55 | } elseif ($isCmd === '1') { 56 | // print($callTrait->config['client_id']); 57 | $msgData = sendAppButtons($jsMsg); 58 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 59 | $conn->send($msg); 60 | }//end of pay1 61 | 62 | elseif ($isCmd === '2') { 63 | // print($callTrait->config['client_id']); 64 | $msgData = sendAppCard($jsMsg); 65 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 66 | $conn->send($msg); 67 | }//end of pay2 68 | elseif ($isCmd === '3') { 69 | transfer(); 70 | } else { 71 | $msgData = sendPlainText($jsMsg->data->conversation_id, 72 | base64_decode($jsMsg->data->data)); 73 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 74 | $conn->send($msg); 75 | } 76 | } //end of PLAIN_TEXT 77 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 78 | // refundInstant 79 | echo "user id:".$jsMsg->data->user_id; 80 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 81 | print_r($dtPay); 82 | if ($dtPay->amount > 0) { 83 | echo "paid!".$dtPay->asset_id; 84 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 85 | } 86 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 87 | } //end of CREATE_MESSAGE 88 | 89 | }); 90 | 91 | $conn->on('close', function($code = null, $reason = null) { 92 | echo "Connection closed ({$code} - {$reason})\n"; 93 | }); 94 | /* start listen for the incoming message */ 95 | $message = [ 96 | 'id' => Uuid::uuid4()->toString(), 97 | 'action' => 'LIST_PENDING_MESSAGES', 98 | ]; 99 | print_r(json_encode($message)); 100 | $msg = new Frame(gzencode(json_encode($message)),true,Frame::OP_BINARY); 101 | $conn->send($msg); 102 | // $conn->send(gzencode($msg,1,FORCE_DEFLATE)); 103 | }, function(\Exception $e) use ($loop) { 104 | echo "Could not connect: {$e->getMessage()}\n"; 105 | $loop->stop(); 106 | }); 107 | 108 | $loop->run(); 109 | 110 | 111 | function sendUsage($conversation_id):Array { 112 | $msgHelp = << $conversation_id, 125 | 'category' => 'PLAIN_TEXT', 126 | 'status' => 'SENT', 127 | 'message_id' => Uuid::uuid4()->toString(), 128 | 'data' => base64_encode($msgContent),//base64_encode("hello!"), 129 | ]; 130 | $msgPayButton = [ 131 | 'id' => Uuid::uuid4()->toString(), 132 | 'action' => 'CREATE_MESSAGE', 133 | 'params' => $msgParams, 134 | ]; 135 | return $msgPayButton; 136 | } 137 | function sendAppButtons($jsMsg):Array { 138 | $payLinkEOS = "https://mixin.one/pay?recipient=". 139 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 140 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 141 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 142 | "&memo="; 143 | $payLinkBTC = "https://mixin.one/pay?recipient=". 144 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 145 | "c6d0c728-2624-429b-8e0d-d9d19b6592fa". 146 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 147 | "&memo="; 148 | $msgData = [[ 149 | 'label' => "Pay 0.001 EOS", 150 | 'color' => "#FFABAB", 151 | 'action' => $payLinkEOS, 152 | ],[ 153 | 'label' => "Pay 0.0001 BTC", 154 | 'color' => "#00EEFF", 155 | 'action' => $payLinkBTC, 156 | ], 157 | ]; 158 | $msgParams = [ 159 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 160 | // 'recipient_id' => $jsMsg->data->user_id, 161 | 'category' => 'APP_BUTTON_GROUP',//'PLAIN_TEXT', 162 | 'status' => 'SENT', 163 | 'message_id' => Uuid::uuid4()->toString(), 164 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 165 | ]; 166 | $msgPayButtons = [ 167 | 'id' => Uuid::uuid4()->toString(), 168 | 'action' => 'CREATE_MESSAGE', 169 | 'params' => $msgParams, 170 | ]; 171 | return $msgPayButtons; 172 | } 173 | 174 | function sendAppCard($jsMsg):Array 175 | { 176 | $payLink = "https://mixin.one/pay?recipient=". 177 | "a1ce2967-a534-417d-bf12-c86571e4eefa"."&asset=". 178 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 179 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 180 | "&memo="; 181 | $msgData = [ 182 | 'icon_url' => "https://mixin.one/assets/98b586edb270556d1972112bd7985e9e.png", 183 | 'title' => "Pay 0.001 EOS", 184 | 'description' => "pay", 185 | 'action' => $payLink, 186 | ]; 187 | $msgParams = [ 188 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 189 | // 'recipient_id' => $jsMsg->data->user_id, 190 | 'category' => 'APP_CARD',//'PLAIN_TEXT', 191 | 'status' => 'SENT', 192 | 'message_id' => Uuid::uuid4()->toString(), 193 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 194 | ]; 195 | $msgPayButton = [ 196 | 'id' => Uuid::uuid4()->toString(), 197 | 'action' => 'CREATE_MESSAGE', 198 | 'params' => $msgParams, 199 | ]; 200 | return $msgPayButton; 201 | } 202 | 203 | function transfer() { 204 | $mixinSdk = new MixinSDK(require './config.php'); 205 | print_r($mixinSdk->getConfig()); 206 | } 207 | 208 | function generateReceipt($msgID):Array { 209 | $IncomingMsg = ["message_id" => $msgID, "status" => "READ"]; 210 | $RspMsg = ["id" => Uuid::uuid4()->toString(), "action" => "ACKNOWLEDGE_MESSAGE_RECEIPT", 211 | "params" => $IncomingMsg]; 212 | return $RspMsg; 213 | } 214 | function refundInstant($_assetID,$_amount,$_opponent_id) { 215 | $mixinSdk = new MixinSDK(require './config.php'); 216 | // print_r(); 217 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 218 | $mixinSdk->getConfig()['default']['pin'],$_amount); 219 | print_r($BotInfo); 220 | } 221 | ``` 222 | ### Olá Bitcoin 223 | Execute **php app.php** no diretório do projeto. 224 | 225 | ```bash 226 | php app.php 227 | ``` 228 | 229 | ```bash 230 | wenewzha:mixin_labs-php-bot wenewzhang$ php app.php 231 | a1ce2967-a534-417d-bf12-c86571e4eefa{"id":"12c7a470-d6a4-403d-94e8-e6f8ae833971","action":"LIST_PENDING_MESSAGES"}stdClass Object 232 | ( 233 | [id] => 12c7a470-d6a4-403d-94e8-e6f8ae833971 234 | [action] => LIST_PENDING_MESSAGES 235 | ) 236 | ``` 237 | O bot se conecta com o mixin.one com sucesso quando a saída do console é "LIST_PENDING_MESSAGES". 238 | 239 | ![pay-links](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/pay-links.jpg) 240 | 241 | O bot te disse como interagir: 242 | - **1** O bot manda um link APP_CARD. 243 | - **2** O bot manda um link APP_BUTTON_GROUP. 244 | - **? ou help** para ajuda! 245 | Clique nos links na página de conversa, insira o código PIN para pagar moeda para o bot. 246 | ![click-pay-link-to-pay](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/click-link-to-pay.jpg) 247 | 248 | Completa [introdução às mensagens do Mixin Messenger](https://developers.mixin.one/api/beta-mixin-message/websocket-messages/). 249 | 250 | O usuário pode pagar 0.001 Bitcoin para o bot, os 0.001 Bitcoin serão devolvidos em 1 segundo. De fato, o usuário pode pagar em qualquer moeda. 251 | ![pay-link](https://github.com/wenewzhang/mixin_network-nodejs-bot2/raw/master/Pay_and_refund_quickly.jpg) 252 | 253 | O desenvolvedor pode enviar Bitcoin para seus bots na página de conversa. O bot enviará de volta imediatamente após receber o Bitcoin. 254 | ![transfer Bitcoin](https://github.com/wenewzhang/mixin_network-nodejs-bot2/raw/master/transfer-any-tokens.jpg) 255 | 256 | ## Resumo do código fonte 257 | ```php 258 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 259 | $conn->send($msg); 260 | ``` 261 | O bot envia mensagem para o usuário, O qual usa json para serializar e então usa gzencode para comprimir. 262 | 263 | ```php 264 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 265 | // refundInstant 266 | echo "user id:".$jsMsg->data->user_id; 267 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 268 | print_r($dtPay); 269 | if ($dtPay->amount > 0) { 270 | echo "paid!".$dtPay->asset_id; 271 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 272 | } 273 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 274 | ``` 275 | 276 | * O valor $dtPay-> é negativo se o bot envia Bitcoin para o usuário com sucesso. 277 | * O valor $dtPay-> é positivo se o bot receber Bitcoin. 278 | 279 | O seguinte código transfere o Bitcoin para o usuário. 280 | ```php 281 | function refundInstant($_assetID,$_amount,$_opponent_id) { 282 | $mixinSdk = new MixinSDK(require './config.php'); 283 | // print_r(); 284 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 285 | $mixinSdk->getConfig()['default']['pin'],$_amount); 286 | print_r($BotInfo); 287 | } 288 | 289 | ``` 290 | 291 | 292 | O código completo está [aqui](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/app.php) 293 | -------------------------------------------------------------------------------- /README3-spanish.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README3-zhchs.md: -------------------------------------------------------------------------------- 1 | # 基于Mixin Network的PHP比特币开发教程: 创建比特币钱包 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 我们已经创建过一个[回复消息](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README-zhchs.md)的机器人和一个能自动[支付比特币](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2-zhchs.md)的机器人. 4 | 5 | ### 通过本教程的学习,你可以学到如下内容 6 | 1. 如何创建一个比特币钱包. 7 | 2. 如何读取比特币钱包的余额. 8 | 3. 如何支付比特币并即时确认. 9 | 4. 如何将Mixin Network的比特币提现到你的冷钱包或第三方交易所. 10 | 11 | 12 | 前期准备:你要有一个Mixin Network账户。如果没有账户,一行代码就能创建一个 13 | ```php 14 | $user_info = $mixinSdk->Network()->createUser("Tom cat"); 15 | ``` 16 | 上面的语句会在本地创建一个RSA密钥对,然后调用Mixin Network来创建帐号,最后输出帐号信息. 17 | ```php 18 | //Create User api include all account information 19 | print_r($user_info); 20 | print($user_info["pubKey"]); 21 | $newConfig = array(); 22 | $newConfig["private_key"] = $user_info["priKey"]; 23 | $newConfig["pin_token"] = $user_info["pin_token"]; 24 | $newConfig["session_id"] = $user_info["session_id"]; 25 | $newConfig["client_id"] = $user_info["user_id"]; 26 | ``` 27 | 28 | 帐号创建成功后结果如下: 29 | ```php 30 | Array 31 | ( 32 | [type] => user 33 | [user_id] => de06f952-6ec7-3789-8467-9aa79869a6ef 34 | [identity_number] => 0 35 | [full_name] => Tom cat 36 | [avatar_url] => 37 | [relationship] => 38 | [mute_until] => 0001-01-01T00:00:00Z 39 | [created_at] => 2019-02-20T12:29:29.86008273Z 40 | [is_verified] => 41 | [session_id] => bc9293e5-ed9a-48da-99f9-915f561a1c60 42 | [phone] => 43 | [pin_token] => TIPyCtRTTYOg2sr+lu0z2D3xS8SOtQAy0ZDnacRrn6u2ytutZinzeEpRTD9N1+DS/T1zJ8VoX4ED19nhF5SApjqjUaRjKI5lga4rQGcePjCvM0D89FdpmKJzNMLjzV2DglKFMPbnJTu1btfILc0XWiSNEiiFr2mHuLI7bYuQzWI= 44 | [invitation_code] => 45 | [code_id] => 46 | [code_url] => https://mixin.one/codes/ 47 | [has_pin] => 48 | [receive_message_source] => EVERYBODY 49 | [accept_conversation_source] => EVERYBODY 50 | [priKey] => -----BEGIN PRIVATE KEY----- 51 | MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALh0dSy2GcKek/Jp 52 | 4lTMZxJ30AWP+inZ4c+FG+3ch3fenmXysCyM56hgvVZwh4RrRpvVjRt/NNE3k2Wg 53 | N9LNZqWXCmo4ae/hJjpwuj/EVR/1/HSebF9hcvMoTre8D0iLlk+rf1tgr/ZHmIoa 54 | 8ef45xMBDargfsF4b5k7kUavU9/xAgMBAAECgYB1ShBMOwsMVxvKdIvn0gXkl20e 55 | bFvtis9szr5gtO8rSNK+DuD5oyuXRNSAh5OUn0ZJxzQv/OZP9x/x6jw0/kk7Aj6c 56 | jjN3beC7UoayDYms4yNFoWNPqZEXkQ0b2tRsF3mdNj6LVm6Gq7FPDD1TYJ4GR4eO 57 | cWHCkZWym26HbZ30AQJBAPNFeZ7nd9wQIzu0wN9isrZebnCko3yax64MDsUAsrmP 58 | B1wdHkdX0tJpCldighYD10Cyi+nSz3ODmmbPbLu8AjECQQDCGyi0lpCoV+skLVR0 59 | 4weU99Msz1neqOw1khQCJLzUW8UdDhsVwfCdzCeuZrCz+gl/aZaJ6d+6rNTMp1hL 60 | ionBAkBEs34hTiUfVL9egTFm5KyrrAdscFJrQhraIDWblRLkLGxbqy194GN9YIS3 61 | IO6z4OnNL58rrYlAig30sud2LSZBAkEAjuNXT7kWvBYcbwE/jtwhlLPqrK3nRlWr 62 | rLPgLsPEjb8Ql5busVGXQ1IqU+QcaCDEJRshSlzz6YOZEx6NjO5rAQJAejvW3DmT 63 | RjUSDJD8hGr9eCpKQTBDXyUEvyLIMCuRmm9Cbz0HRl4aVXOVblVWoJ6YsGvbCkSl 64 | LQCrPL2T58JTkg== 65 | -----END PRIVATE KEY----- 66 | 67 | [pubKey] => -----BEGIN PUBLIC KEY----- 68 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4dHUsthnCnpPyaeJUzGcSd9AF 69 | j/op2eHPhRvt3Id33p5l8rAsjOeoYL1WcIeEa0ab1Y0bfzTRN5NloDfSzWallwpq 70 | OGnv4SY6cLo/xFUf9fx0nmxfYXLzKE63vA9Ii5ZPq39bYK/2R5iKGvHn+OcTAQ2q 71 | 4H7BeG+ZO5FGr1Pf8QIDAQAB 72 | -----END PUBLIC KEY----- 73 | ) 74 | ``` 75 | 现在你需要小心保管好你的帐号信息,在读取该账户的比特币资产余额或者进行其他操作时,将需要用到这些信息. 76 | ### 给新建的帐号创建一个比特币钱包 77 | 新账号并不默认内置比特币钱包, 现在读一下比特币余额就可以创建一个比特币钱包。 78 | ```php 79 | $asset_infoNew = $mixinSdkNew->Wallet()->readAsset("c6d0c728-2624-429b-8e0d-d9d19b6592fa"); 80 | echo "BitCoin wallet address is :".$asset_infoNew["public_key"]; 81 | ``` 82 | 创建的帐号的比特币资产详细信息如下,其中public key就是比特币的存币地址: 83 | ```php 84 | Array 85 | ( 86 | [type] => asset 87 | [asset_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa 88 | [chain_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa 89 | [symbol] => BTC 90 | [name] => Bitcoin 91 | [icon_url] => https://images.mixin.one/HvYGJsV5TGeZ-X9Ek3FEQohQZ3fE9LBEBGcOcn4c4BNHovP4fW4YB97Dg5LcXoQ1hUjMEgjbl1DPlKg1TW7kK6XP=s128 92 | [balance] => 0 93 | [public_key] => 195p8R8Y15uzDGMrdVkELVUW2444psqiSq 94 | [account_name] => 95 | [account_tag] => 96 | [price_btc] => 1 97 | [price_usd] => 3928.11498197 98 | [change_btc] => 0 99 | [change_usd] => -0.006841408545228452 100 | [asset_key] => c6d0c728-2624-429b-8e0d-d9d19b6592fa 101 | [confirmations] => 12 102 | [capitalization] => 0 103 | ) 104 | ``` 105 | 106 | 这个API能够提供若干与比特币有关的信息: 107 | * 存币地址:[public_key] 108 | * Logo: [icon_url] 109 | * 资产名字:[name] 110 | * 资产在Mixin Network的uuid: [asset_key] 111 | * 对美元的价格(Coinmarketcap.com提供): [price_usd] 112 | * 存币时确认的区块数量:[confirmations] 113 | 114 | 115 | ### 比特币私钥呢? 116 | 比特币的私钥呢?这个私钥被Mixin Network通过多重签名保护,所以对用户来说是不可见的,比特币资产的提现和转账都需要用户提供正确的的RSA签名,PIN代码与会话密钥才能完成. 117 | 118 | ### 不只是比特币,还有以太坊,EOS等 119 | 这个帐号不只支持比特币,还支持以太坊,EOS等, 完整的区块链支持[列表](https://mixin.one/network/chains). 这个账户同时也支持所有的 ERC20 代币与 EOS 代币. 120 | 121 | 创建其它的币的钱包与创建比特币钱包过程一样,读对应的资产余额就可以. 122 | 123 | #### Mixin Network 当前支持的加密货币 (2019-02-19) 124 | 125 | |crypto |uuid in Mixin Network 126 | |---|--- 127 | |EOS|6cfe566e-4aad-470b-8c9a-2fd35b49c68d 128 | |CNB|965e5c6e-434c-3fa9-b780-c50f43cd955c 129 | |BTC|c6d0c728-2624-429b-8e0d-d9d19b6592fa 130 | |ETC|2204c1ee-0ea2-4add-bb9a-b3719cfff93a 131 | |XRP|23dfb5a5-5d7b-48b6-905f-3970e3176e27 132 | |XEM|27921032-f73e-434e-955f-43d55672ee31 133 | |ETH|43d61dcd-e413-450d-80b8-101d5e903357 134 | |DASH|6472e7e3-75fd-48b6-b1dc-28d294ee1476 135 | |DOGE|6770a1e5-6086-44d5-b60f-545f9d9e8ffd 136 | |LTC|76c802a2-7c88-447f-a93e-c29c9e5dd9c8 137 | |SC|990c4c29-57e9-48f6-9819-7d986ea44985 138 | |ZEN|a2c5d22b-62a2-4c13-b3f0-013290dbac60 139 | |ZEC|c996abc9-d94e-4494-b1cf-2a3fd3ac5714 140 | |BCH|fd11b6e3-0b87-41f1-a41f-f0e9b49e5bf0 141 | 142 | EOS的存币地址与其它的币有些不同,它由两部分组成: account_name and account tag, 如果你向Mixin Network存入EOS,你需要填两项数据: account name 是**eoswithmixin**,备注里输入你的account_tag,比如**0aa2b00fad2c69059ca1b50de2b45569**. 143 | 144 | EOS的资产余额返回结果如下: 145 | ```php 146 | Array 147 | ( 148 | [type] => asset 149 | [asset_id] => 6cfe566e-4aad-470b-8c9a-2fd35b49c68d 150 | [chain_id] => 6cfe566e-4aad-470b-8c9a-2fd35b49c68d 151 | [symbol] => EOS 152 | [name] => EOS 153 | [icon_url] => https://images.mixin.one/a5dtG-IAg2IO0Zm4HxqJoQjfz-5nf1HWZ0teCyOnReMd3pmB8oEdSAXWvFHt2AJkJj5YgfyceTACjGmXnI-VyRo=s128 154 | [balance] => 0 155 | [public_key] => 156 | [account_name] => eoswithmixin 157 | [account_tag] => 0aa2b00fad2c69059ca1b50de2b45569 158 | [price_btc] => 0.00097367 159 | [price_usd] => 3.87734515 160 | [change_btc] => 0.05950956117519646 161 | [change_usd] => 0.07238079041492786 162 | [asset_key] => eosio.token:EOS 163 | [confirmations] => 64 164 | [capitalization] => 0 165 | ) 166 | ``` 167 | 168 | ### 存入比特币与读取比特币余额 169 | 现在,你可以向比特币的钱包存币了。 170 | 171 | 当然,在比特币网络里转币,手续费是相当贵的,费用的中位数在0.001BTC,按当前4000美元的价格,在4美元左右,有一个方便的办法,如果你有[Mixin Messenger](https://mixin.one/messenger)帐号,里面并且有比特币的话,可以直接提现比特币到新创建的帐号的比特币充值地址,它们在同一个Mixin Network网络内,手续费为0,而且1秒到账。 172 | 173 | 下面的代码,可以读取比特币钱包余额. 174 | ```php 175 | $btc = $mixinSdkNew->Wallet()->readAsset("c6d0c728-2624-429b-8e0d-d9d19b6592fa"); 176 | print_r($btc); 177 | ``` 178 | ### Mixin Network网内免手续费的,并且即时确认 179 | 任何币在Mixin Network内部的交易,都是无手续费的,并且立刻到账。 180 | 前期准备: 账户设置了PIN 181 | 182 | 对于新创建的帐号,我们通过updatePin来设置新PIN码, 代码如下: 183 | ```php 184 | //Create a PIN. 185 | $pinInfo = $mixinSdkNew->Pin()->updatePin('',PIN); 186 | print_r($pinInfo); 187 | ``` 188 | #### Mixin Network帐号之间的比特币支付 189 | 通过Mixin Messenger,我们可以先转比特币给机器人,然后让机器人转币给新用户。 190 | ```php 191 | $mixinSdk = new MixinSDK(require './config.php'); 192 | //$user_info["user_id"] generated by create user; 193 | $trans_info = $mixinSdk->Wallet()->transfer(BTC_ASSET_ID,$user_info["user_id"], 194 | $mixinSdk->getConfig()['default']['pin'],AMOUNT); 195 | print_r($trans_info); 196 | ``` 197 | 198 | 读取Bitcoin的余额,来确认比特币是不是转成功了! 注意**$mixinSdkNew**是新用户的。 199 | ```php 200 | $btc = $mixinSdkNew->Wallet()->readAsset(BTC_ASSET_ID); 201 | print_r($btc); 202 | ``` 203 | ### 如何将比特币存入你的冷钱包或者第三方交易所 204 | 如果你希望将币存入你的冷钱包或者第三方交易所, 先要得到冷钱包或者你在第三方交易所的钱包地址,然后将钱包地址提交到Mixin Network. 205 | 206 | - **要点提示**: 提现是需要支付收续费的,准备好比特币包地址! 207 | 208 | #### 增加目的钱包地址到Mixin Network 209 | 调用createAddress API, 将会返回一个address_id,下一步的提现操作会用到这个id。 210 | ```php 211 | $btcInfo = $mixinSdkNew->Wallet()->createAddress("c6d0c728-2624-429b-8e0d-d9d19b6592fa", 212 | "14T129GTbXXPGXXvZzVaNLRFPeHXD1C25C", 213 | $mixinSdkNew->getConfig()['default']['pin'], 214 | "BTC withdral",false); 215 | ``` 216 | 这里的 **14T129GTbXXPGXXvZzVaNLRFPeHXD1C25C** 就是一个比特币钱包地址, 如下所示,提现费用是0.0025738 BTC, address_id 是"345855b5-56a5-4f3b-ba9e-d99601ef86c1". 217 | ```php 218 | Array 219 | ( 220 | [type] => address 221 | [address_id] => 345855b5-56a5-4f3b-ba9e-d99601ef86c1 222 | [asset_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa 223 | [public_key] => 14T129GTbXXPGXXvZzVaNLRFPeHXD1C25C 224 | [label] => BTC withdral 225 | [account_name] => 226 | [account_tag] => 227 | [fee] => 0.0025738 228 | [reserve] => 0 229 | [dust] => 0.0001 230 | [updated_at] => 2019-02-20T01:47:56.44067294Z 231 | ) 232 | ``` 233 | 234 | 235 | #### 创建提现地址成功后,你可以用readAddress读取最新的提现费。 236 | ```php 237 | $wdInfo = $mixinSdkNew->Wallet()->readAddress($btcInfo["address_id"]); 238 | ``` 239 | 240 | #### 提交提现请求,Mixin Network会即时处理提现请求. 241 | 提交提现请求到Mixin Network, $btcInfo["address_id"]就是createAddress创建的。 242 | ```php 243 | $wdInfo = $mixinSdkNew->Wallet()->withdrawal($btcInfo["address_id"], 244 | "0.01", 245 | $mixinSdkBot->getConfig()['default']['pin'], 246 | "BTC withdral"); 247 | ``` 248 | #### 可以通过blockchain explore来查看进度. 249 | 250 | [完整的代码在这儿](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/call_apis.php) 251 | -------------------------------------------------------------------------------- /README4-russian.md: -------------------------------------------------------------------------------- 1 | # Как торговать биткойнами с помощью PHP (часть IV) 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | ## Решение номер один: оплата с использованием API ExinCore 5 | [Exincore](https://github.com/exinone/exincore) предоставляет API для коммерческой торговли на Mixin Network. 6 | 7 | Вы вносите оплату в USDT на ExinCore, ExinCore конвертирует их по разумному курсу в биткойны и с очень низкой комиссией переводит вам. Каждая транзакция анонимна и может быть проверена на обозревателе блокчейна. Подробности известны только вам и ExinCore. 8 | 9 | ExinCore не знает, кто вы, потому что использует только `UUID` клиента. 10 | 11 | ### Предварительное условие: 12 | нужно создать бот на базе Mixin Network. Создать его можно, обратившись к [туториалу по PHP для работы с биткойном](https://github.com/wenewzhang/mixin_labs-php-bot). 13 | 14 | #### Установите необходимые пакеты 15 | Как вы уже знаете, мы представляем mixin-sdk-php в [части 1](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README-russian.md). Будем считать, что он уже установлен. Теперь установим **uuid, msgpack**. 16 | ```bash 17 | composer require ramsey/uuid 18 | composer require rybakit/msgpack 19 | ``` 20 | #### Положите USDT или биткойн на депозит в своей учётной записи Mixin Network и проверьте баланс 21 | ExinCore может производить обмен Bitcoin, USDT, EOS, Eth и т. д. Мы покажем, как производить обмен USDT на биткойн. 22 | Проверьте баланс и адрес кошелька до отправки ордера. 23 | 24 | - Проверьте адрес и баланс, запомните адрес биткойн-кошелька. 25 | - Внесите биткойн на адрес этого биткойн-кошелька. 26 | - Проверьте баланс биткойн-кошелька через 100 минут. 27 | 28 | **Кстати, адреса биткойн и USDT не отличаются.** 29 | 30 | ```php 31 | if ($line == '2') { 32 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 33 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 34 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 35 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 36 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 37 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 38 | } 39 | fclose($handle); 40 | } else print("Create user first\n"); 41 | } 42 | if ($line == '3') { 43 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 44 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 45 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 46 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(USDT_ASSET_ID); 47 | print_r("USDT wallet address is :".$asset_info["public_key"]."\n"); 48 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 49 | } 50 | fclose($handle); 51 | } else print("Create user first\n"); 52 | } 53 | ``` 54 | #### Проверьте курс обмена 55 | Как проверить курс обмена монет? Необходимо понимать, что такое базовая монета. Если вы покупаете биткойн, а продаёте USDT, то базовой монетой будет USDT. Если вы покупаете USDT, а продаёте биткойн, то базовой монетой будет биткойн. 56 | ```php 57 | function getExchangeCoins($base_coin) :string { 58 | $client = new GuzzleHttp\Client(); 59 | $res = $client->request('GET', 'https://exinone.com/exincore/markets?base_asset='.$base_coin, [ 60 | ]); 61 | $result = ""; 62 | if ($res->getStatusCode() == "200") { 63 | // echo $res->getStatusCode() . PHP_EOL; 64 | $resInfo = json_decode($res->getBody(), true); 65 | echo "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 66 | $result = "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 67 | foreach ($resInfo["data"] as $key => $coinInfo) { 68 | echo ($coinInfo["exchange_asset"] ." ".$coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 69 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "); 70 | $result .= $coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 71 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "; 72 | foreach ($coinInfo["exchanges"] as $key => $exchange) { 73 | echo $exchange . " "; 74 | $result .= $exchange . " "; 75 | } 76 | echo PHP_EOL; 77 | $result .= PHP_EOL; 78 | } 79 | } 80 | return $result; 81 | } 82 | ``` 83 | 84 | #### Создайте `memo` для подготовки ордера 85 | Во второй части « [Возврат биткойна](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2.md)» мы рассказывали, как отправить монеты. Но ExinCore должна знать, какие монеты вы хотите купить. Для этого нужно записать в `memo` нужный актив. 86 | ```php 87 | $memo = base64_encode(MessagePack::pack([ 88 | 'A' => Uuid::fromString($_targetAssetID)->getBytes(), 89 | ])); 90 | ``` 91 | #### Создайте `memo` и заплатите биткойнами через шлюз API 92 | Отправляйте биткойн(`BTC_ASSET_ID`) на ExinCore(`EXIN_BOT`) и укажите `UUID` нужного актива в `memo` — без него ExinCore сразу же вернет монету! 93 | ```php 94 | const EXIN_BOT = "61103d28-3ac2-44a2-ae34-bd956070dab1"; 95 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 96 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 97 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 98 | coinExchange(BTC_ASSET_ID,"0.0001",USDT_ASSET_ID); 99 | 100 | //........... 101 | 102 | function coinExchange($_assetID,$_amount,$_targetAssetID) { 103 | $mixinSdk = new MixinSDK(require './config.php'); 104 | // print_r(); 105 | $memo = base64_encode(MessagePack::pack([ 106 | 'A' => Uuid::fromString($_targetAssetID)->getBytes(), 107 | ])); 108 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,EXIN_BOT, 109 | $mixinSdk->getConfig()['default']['pin'],$_amount,$memo); 110 | print_r($BotInfo); 111 | } 112 | ``` 113 | ExinCore должна отправить требуемую монету вашему боту, указав в `memo` свою комиссию, идентификатор ордера, курс и т.д. (См. пример ниже). 114 | - **readUserSnapshots** — вывести краткую информацию о балансе пользователя 115 | ```php 116 | $limit = 20; 117 | $offset = '2019-03-10T01:58:25.362528Z'; 118 | $snapInfo = $mixinSdk_BotInstance->Wallet()->readUserSnapshots($limit, $offset); 119 | // print_r($networkInfo2); 120 | foreach ($snapInfo as $record) { 121 | // echo $key . PHP_EOL; 122 | // print_r($record); 123 | if ($record['amount'] > 0 and $record['memo'] != '') { 124 | echo "------------MEMO:-coin--exchange--------------" . PHP_EOL; 125 | echo "memo: " . $record['memo'] . PHP_EOL; 126 | // print_r($dtPay->memo); 127 | echo "You Get Coins: ". $record['asset_id']. " " . $record['amount'] . PHP_EOL; 128 | $memoUnpack = MessagePack::unpack(base64_decode($record['memo'])); 129 | $feeAssetID = Uuid::fromBytes($memoUnpack['FA'])->toString(); 130 | $OrderID = Uuid::fromBytes($memoUnpack['O'])->toString(); 131 | if ($memoUnpack['C'] == 1000) { 132 | echo "Successful Exchange:". PHP_EOL; 133 | echo "Fee asset ID: " . $feeAssetID . " fee is :" . $memoUnpack['F'] . PHP_EOL; 134 | echo "Order ID: " . $OrderID . " Price is :" . $memoUnpack['P'] . PHP_EOL; 135 | } else print_r($memoUnpack); 136 | echo "--------------memo-record end---------------" . PHP_EOL; 137 | } 138 | } 139 | ``` 140 | 141 | Если обмен произведен успешно, консоль выведет следующее: 142 | ```bash 143 | ------------MEMO:-coin--exchange-------------- 144 | memo: hqFDzQPooVCnMzg3Mi45N6FGqTAuMDAwNzc0NqJGQcQQgVsLGidkNzaPqkLWlPpiCqFUoUahT8QQIbfeL6p5RVOcEP0mLb+t+g== 145 | You Get Coins: 815b0b1a-2764-3736-8faa-42d694fa620a 0.3857508 146 | Successful Exchange: 147 | Fee asset ID: 815b0b1a-2764-3736-8faa-42d694fa620a fee is :0.0007746 148 | Order ID: 21b7de2f-aa79-4553-9c10-fd262dbfadfa Price is :3872.97 149 | --------------memo-record end--------------- 150 | ``` 151 | 152 | #### Проверьте баланс кошелька 153 | Проверьте и отразите баланс кошелька. 154 | ```php 155 | $mixinSdk = new MixinSDK(require './config.php'); 156 | $asset_info = $mixinSdk->Wallet()->readAsset(USDT_ASSET_ID); 157 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 158 | ``` 159 | ## Как пользоваться исходным кодом 160 | Выполните команду **php call_apis.php** для запуска меню. 161 | 162 | - 1: Создать пользователя и обновить ПИН 163 | - 2: Проверить баланс и адрес биткойн-кошелька 164 | - 3: Проверить баланс и адрес USDT-кошелька 165 | - 4: Проверить баланс EOS-кошелька 166 | - 5: Проверить адрес EOS-кошелька 167 | - 6: Перевести биткойн от бота новому пользователю 168 | - 7: Перевести биткойн от нового пользователя на мастер-счёт 169 | - 8: Вывести биткойн через бота 170 | - 9: Вывести EOS через бота 171 | - qu: Проверить курс (USDT) 172 | - qb: Проверить курс (BTC) 173 | - b: Проверить баланс бота (USDT и BTC) 174 | - s: Вывести краткую информацию 175 | - tb: Перевести 0.0001 биткойн для покупки USDT 176 | - tu: Перевести $1 USDT для покупки биткойна 177 | - q: Выйти 178 | 179 | [Исходный код полностью](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/call_apis.php) 180 | 181 | ## Решение номер два: Отправьте ордер на биржу Ocean.One 182 | -------------------------------------------------------------------------------- /README4-spanish.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README4-zhchs.md: -------------------------------------------------------------------------------- 1 | # 如何用 PHP 买卖Bitcoin 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | ## 方案一: 通过ExinCore API进行币币交易 5 | [Exincore](https://github.com/exinone/exincore) 提供了基于Mixin Network的币币交易API. 6 | 7 | 你可以支付USDT给ExinCore, ExinCore会以最低的价格,最优惠的交易费将你购买的比特币转给你, 每一币交易都是匿名的,并且可以在区块链上进行验证,交易的细节只有你与ExinCore知道! 8 | 9 | ExinCore 也不知道你是谁,它只知道你的UUID. 10 | 11 | ### 预备知识: 12 | 你先需要创建一个机器人, 方法在 [教程一](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README-zhchs.md). 13 | 14 | #### 安装依赖包 15 | 正如教程一里我们介绍过的, 我们需要依赖 **mixin-sdk-php**, 你应该先安装过它了, 这儿我们再安装 **uuid, msgpack** 两个软件包. 16 | ```bash 17 | composer require ramsey/uuid 18 | composer require rybakit/msgpack 19 | ``` 20 | #### 充币到 Mixin Network, 并读出它的余额. 21 | ExinCore可以进行BTC, USDT, EOS, ETH 等等交易, 这儿演示如果用 USDT购买BTC 或者 用BTC购买USDT, 交易前,先检查一下钱包地址! 22 | 完整的步骤如下: 23 | - 检查比特币或USDT的余额,钱包地址。并记下钱包地址。 24 | - 从第三方交易所或者你的冷钱包中,将币充到上述钱包地址。 25 | - 再检查一下币的余额,看到帐与否。(比特币的到帐时间是5个区块的高度,约100分钟)。 26 | 27 | **请注意,比特币与USDT的地址是一样的。** 28 | ```php 29 | if ($line == '2') { 30 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 31 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 32 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 33 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 34 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 35 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 36 | } 37 | fclose($handle); 38 | } else print("Create user first\n"); 39 | } 40 | if ($line == '3') { 41 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 42 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 43 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 44 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(USDT_ASSET_ID); 45 | print_r("USDT wallet address is :".$asset_info["public_key"]."\n"); 46 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 47 | } 48 | fclose($handle); 49 | } else print("Create user first\n"); 50 | } 51 | ``` 52 | #### 查询ExinCore市场的价格信息 53 | 如果来查询ExinCore市场的价格信息呢?你要先了解你交易的基础币是什么,如果你想买比特币,卖出USDT,那么基础货币就是USDT;如果你想买USDT,卖出比特币,那么基础货币就是比特币. 54 | ```php 55 | function getExchangeCoins($base_coin) :string { 56 | $client = new GuzzleHttp\Client(); 57 | $res = $client->request('GET', 'https://exinone.com/exincore/markets?base_asset='.$base_coin, [ 58 | ]); 59 | $result = ""; 60 | if ($res->getStatusCode() == "200") { 61 | // echo $res->getStatusCode() . PHP_EOL; 62 | $resInfo = json_decode($res->getBody(), true); 63 | echo "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 64 | $result = "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 65 | foreach ($resInfo["data"] as $key => $coinInfo) { 66 | echo ($coinInfo["exchange_asset"] ." ".$coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 67 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "); 68 | $result .= $coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 69 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "; 70 | foreach ($coinInfo["exchanges"] as $key => $exchange) { 71 | echo $exchange . " "; 72 | $result .= $exchange . " "; 73 | } 74 | echo PHP_EOL; 75 | $result .= PHP_EOL; 76 | } 77 | } 78 | return $result; 79 | } 80 | ``` 81 | 82 | #### 交易前,创建一个Memo! 83 | 在第二章里,[基于Mixin Network的PHP比特币开发教程: 机器人接受比特币并立即退还用户](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2-zhchs.md), 我们学习过退还用户比特币,在这里,我们除了给ExinCore支付币外,还要告诉他我们想购买的币是什么,即将想购买的币存到memo里。 84 | ```php 85 | $memo = base64_encode(MessagePack::pack([ 86 | 'A' => Uuid::fromString($_targetAssetID)->getBytes(), 87 | ])); 88 | ``` 89 | #### 币币交易的完整流程 90 | 转币给ExinCore时,将memo写入你希望购买的币,否则,ExinCore会直接退币给你! 91 | ```php 92 | const EXIN_BOT = "61103d28-3ac2-44a2-ae34-bd956070dab1"; 93 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 94 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 95 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 96 | coinExchange(BTC_ASSET_ID,"0.0001",USDT_ASSET_ID); 97 | 98 | //........... 99 | 100 | function coinExchange($_assetID,$_amount,$_targetAssetID) { 101 | $mixinSdk = new MixinSDK(require './config.php'); 102 | // print_r(); 103 | $memo = base64_encode(MessagePack::pack([ 104 | 'A' => Uuid::fromString($_targetAssetID)->getBytes(), 105 | ])); 106 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,EXIN_BOT, 107 | $mixinSdk->getConfig()['default']['pin'],$_amount,$memo); 108 | print_r($BotInfo); 109 | } 110 | ``` 111 | 如果你想卖出比特币买入USDT,调用方式如下: 112 | 113 | ```php 114 | coinExchange($config,BTC_ASSET_ID,"0.0001",USDT_ASSET_ID); 115 | ``` 116 | 117 | 如果你想卖出USDT买入比特币,调用方式如下: 118 | 119 | ```php 120 | coinExchange($config,USDT_ASSET_ID,"1",BTC_ASSET_ID); 121 | ``` 122 | 123 | 交易完成后,Exincore会将你需要的币转到你的帐上,同样,会在memo里,记录成交价格,交易费用等信息!你只需要按下面的方式解开即可! 124 | - **readUserSnapshots** 读取钱包的交易记录。 125 | ```php 126 | $limit = 20; 127 | $offset = '2019-03-10T01:58:25.362528Z'; 128 | $snapInfo = $mixinSdk_BotInstance->Wallet()->readUserSnapshots($limit, $offset); 129 | // print_r($networkInfo2); 130 | foreach ($snapInfo as $record) { 131 | // echo $key . PHP_EOL; 132 | // print_r($record); 133 | if ($record['amount'] > 0 and $record['memo'] != '') { 134 | echo "------------MEMO:-coin--exchange--------------" . PHP_EOL; 135 | echo "memo: " . $record['memo'] . PHP_EOL; 136 | // print_r($dtPay->memo); 137 | echo "You Get Coins: ". $record['asset_id']. " " . $record['amount'] . PHP_EOL; 138 | $memoUnpack = MessagePack::unpack(base64_decode($record['memo'])); 139 | $feeAssetID = Uuid::fromBytes($memoUnpack['FA'])->toString(); 140 | $OrderID = Uuid::fromBytes($memoUnpack['O'])->toString(); 141 | if ($memoUnpack['C'] == 1000) { 142 | echo "Successful Exchange:". PHP_EOL; 143 | echo "Fee asset ID: " . $feeAssetID . " fee is :" . $memoUnpack['F'] . PHP_EOL; 144 | echo "Order ID: " . $OrderID . " Price is :" . $memoUnpack['P'] . PHP_EOL; 145 | } else print_r($memoUnpack); 146 | echo "--------------memo-record end---------------" . PHP_EOL; 147 | } 148 | } 149 | ``` 150 | 151 | 一次成功的交易如下: 152 | ```bash 153 | ------------MEMO:-coin--exchange-------------- 154 | memo: hqFDzQPooVCnMzg3Mi45N6FGqTAuMDAwNzc0NqJGQcQQgVsLGidkNzaPqkLWlPpiCqFUoUahT8QQIbfeL6p5RVOcEP0mLb+t+g== 155 | You Get Coins: 815b0b1a-2764-3736-8faa-42d694fa620a 0.3857508 156 | Successful Exchange: 157 | Fee asset ID: 815b0b1a-2764-3736-8faa-42d694fa620a fee is :0.0007746 158 | Order ID: 21b7de2f-aa79-4553-9c10-fd262dbfadfa Price is :3872.97 159 | --------------memo-record end--------------- 160 | ``` 161 | 162 | #### 读取币的余额 163 | 通过读取币的余额,来确认交易情况! 164 | ```php 165 | $mixinSdk = new MixinSDK(require './config.php'); 166 | $asset_info = $mixinSdk->Wallet()->readAsset(USDT_ASSET_ID); 167 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 168 | ``` 169 | ## 源代码执行 170 | 执行 **php call_apis.php** 即可开始交易了. 171 | 172 | - 1: Create user and update PIN 173 | - 2: Read Bitcoin balance & address 174 | - 3: Read USDT balance & address 175 | - 4: Read EOS balance 176 | - 5: Read EOS address 177 | - 6: Transfer Bitcoin from bot to new user 178 | - 7: Transfer Bitcoin from new user to Master 179 | - 8: Withdraw bot's Bitcoin 180 | - 9: Withdraw bot's EOS 181 | - qu: Read market price(USDT) 182 | - qb: Read market price(BTC) 183 | - b: Balance of bot (USDT & BTC) 184 | - s: Read Snapshots 185 | - tb: Transfer 0.0001 BTC buy USDT 186 | - tu: Transfer $1 USDT buy BTC 187 | - q: Exit 188 | 189 | [完整代码](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/call_apis.php) 190 | 191 | ## Solution Two: List your order on Ocean.One exchange 192 | -------------------------------------------------------------------------------- /README4.md: -------------------------------------------------------------------------------- 1 | # How to trade bitcoin through PHP language 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | ## Solution One: pay to ExinCore API 5 | [Exincore](https://github.com/exinone/exincore) provide a commercial trading API on Mixin Network. 6 | 7 | You pay USDT to ExinCore, ExinCore transfer Bitcoin to you on the fly with very low fee and fair price. Every transaction is anonymous to public but still can be verified on blockchain explorer. Only you and ExinCore know the details. 8 | 9 | ExinCore don't know who you are because ExinCore only know your client's uuid. 10 | 11 | ### Pre-request: 12 | You should have created a bot based on Mixin Network. Create one by reading [PHP Bitcoin tutorial](https://github.com/wenewzhang/mixin_labs-php-bot). 13 | 14 | #### Install required packages 15 | As you know, we introduce you the mixin-sdk-php in [chapter 1](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README.md), assume it has installed before, let's install **uuid, msgpack** here. 16 | ```bash 17 | composer require ramsey/uuid 18 | composer require rybakit/msgpack 19 | ``` 20 | #### Deposit USDT or Bitcoin into your Mixin Network account and read balance 21 | ExinCore can exchange between Bitcoin, USDT, EOS, Eth etc. Here show you how to exchange between USDT and Bitcoin, 22 | Check the wallet's balance & address before you make order. 23 | 24 | - Check the address & balance, remember it Bitcoin wallet address. 25 | - Deposit Bitcoin to this Bitcoin wallet address. 26 | - Check Bitcoin balance after 100 minutes later. 27 | 28 | **By the way, Bitcoin & USDT 's address are the same.** 29 | 30 | ```php 31 | if ($line == '2') { 32 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 33 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 34 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 35 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 36 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 37 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 38 | } 39 | fclose($handle); 40 | } else print("Create user first\n"); 41 | } 42 | if ($line == '3') { 43 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 44 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 45 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 46 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(USDT_ASSET_ID); 47 | print_r("USDT wallet address is :".$asset_info["public_key"]."\n"); 48 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 49 | } 50 | fclose($handle); 51 | } else print("Create user first\n"); 52 | } 53 | ``` 54 | #### Read market price 55 | How to check the coin's price? You need understand what is the base coin. If you want buy Bitcoin and sell USDT, the USDT is the base coin. If you want buy USDT and sell Bitcoin, the Bitcoin is the base coin. 56 | ```php 57 | function getExchangeCoins($base_coin) :string { 58 | $client = new GuzzleHttp\Client(); 59 | $res = $client->request('GET', 'https://exinone.com/exincore/markets?base_asset='.$base_coin, [ 60 | ]); 61 | $result = ""; 62 | if ($res->getStatusCode() == "200") { 63 | // echo $res->getStatusCode() . PHP_EOL; 64 | $resInfo = json_decode($res->getBody(), true); 65 | echo "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 66 | $result = "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 67 | foreach ($resInfo["data"] as $key => $coinInfo) { 68 | echo ($coinInfo["exchange_asset"] ." ".$coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 69 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "); 70 | $result .= $coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 71 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "; 72 | foreach ($coinInfo["exchanges"] as $key => $exchange) { 73 | echo $exchange . " "; 74 | $result .= $exchange . " "; 75 | } 76 | echo PHP_EOL; 77 | $result .= PHP_EOL; 78 | } 79 | } 80 | return $result; 81 | } 82 | ``` 83 | 84 | #### Create a memo to prepare order 85 | The chapter two: [Echo Bitcoin](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2.md) introduce transfer coins. But you need to let ExinCore know which coin you want to buy. Just write your target asset into memo. 86 | ```php 87 | $memo = base64_encode(MessagePack::pack([ 88 | 'A' => Uuid::fromString($_targetAssetID)->getBytes(), 89 | ])); 90 | ``` 91 | #### Pay BTC to API gateway with generated memo 92 | Transfer Bitcoin(BTC_ASSET_ID) to ExinCore(EXIN_BOT), put you target asset uuid in the memo, otherwise, ExinCore will refund you coin immediately! 93 | ```php 94 | const EXIN_BOT = "61103d28-3ac2-44a2-ae34-bd956070dab1"; 95 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 96 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 97 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 98 | coinExchange(BTC_ASSET_ID,"0.0001",USDT_ASSET_ID); 99 | 100 | //........... 101 | 102 | function coinExchange($_assetID,$_amount,$_targetAssetID) { 103 | $mixinSdk = new MixinSDK(require './config.php'); 104 | // print_r(); 105 | $memo = base64_encode(MessagePack::pack([ 106 | 'A' => Uuid::fromString($_targetAssetID)->getBytes(), 107 | ])); 108 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,EXIN_BOT, 109 | $mixinSdk->getConfig()['default']['pin'],$_amount,$memo); 110 | print_r($BotInfo); 111 | } 112 | ``` 113 | The ExinCore should transfer the target coin to your bot, meanwhile, put the fee, order id, price etc. information in the memo, unpack the data like below. 114 | - **readUserSnapshots** Read snapshots of the user. 115 | ```php 116 | $limit = 20; 117 | $offset = '2019-03-10T01:58:25.362528Z'; 118 | $snapInfo = $mixinSdk_BotInstance->Wallet()->readUserSnapshots($limit, $offset); 119 | // print_r($networkInfo2); 120 | foreach ($snapInfo as $record) { 121 | // echo $key . PHP_EOL; 122 | // print_r($record); 123 | if ($record['amount'] > 0 and $record['memo'] != '') { 124 | echo "------------MEMO:-coin--exchange--------------" . PHP_EOL; 125 | echo "memo: " . $record['memo'] . PHP_EOL; 126 | // print_r($dtPay->memo); 127 | echo "You Get Coins: ". $record['asset_id']. " " . $record['amount'] . PHP_EOL; 128 | $memoUnpack = MessagePack::unpack(base64_decode($record['memo'])); 129 | $feeAssetID = Uuid::fromBytes($memoUnpack['FA'])->toString(); 130 | $OrderID = Uuid::fromBytes($memoUnpack['O'])->toString(); 131 | if ($memoUnpack['C'] == 1000) { 132 | echo "Successful Exchange:". PHP_EOL; 133 | echo "Fee asset ID: " . $feeAssetID . " fee is :" . $memoUnpack['F'] . PHP_EOL; 134 | echo "Order ID: " . $OrderID . " Price is :" . $memoUnpack['P'] . PHP_EOL; 135 | } else print_r($memoUnpack); 136 | echo "--------------memo-record end---------------" . PHP_EOL; 137 | } 138 | } 139 | ``` 140 | 141 | If you coin exchange successful, console output like below: 142 | ```bash 143 | ------------MEMO:-coin--exchange-------------- 144 | memo: hqFDzQPooVCnMzg3Mi45N6FGqTAuMDAwNzc0NqJGQcQQgVsLGidkNzaPqkLWlPpiCqFUoUahT8QQIbfeL6p5RVOcEP0mLb+t+g== 145 | You Get Coins: 815b0b1a-2764-3736-8faa-42d694fa620a 0.3857508 146 | Successful Exchange: 147 | Fee asset ID: 815b0b1a-2764-3736-8faa-42d694fa620a fee is :0.0007746 148 | Order ID: 21b7de2f-aa79-4553-9c10-fd262dbfadfa Price is :3872.97 149 | --------------memo-record end--------------- 150 | ``` 151 | 152 | #### Read Bitcoin balance 153 | Check the wallet's balance. 154 | ```php 155 | $mixinSdk = new MixinSDK(require './config.php'); 156 | $asset_info = $mixinSdk->Wallet()->readAsset(USDT_ASSET_ID); 157 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 158 | ``` 159 | ## Source code usage 160 | Execute **php call_apis.php** to run it. 161 | 162 | - 1: Create user and update PIN 163 | - 2: Read Bitcoin balance & address 164 | - 3: Read USDT balance & address 165 | - 4: Read EOS balance 166 | - 5: Read EOS address 167 | - 6: Transfer Bitcoin from bot to new user 168 | - 7: Transfer Bitcoin from new user to Master 169 | - 8: Withdraw bot's Bitcoin 170 | - 9: Withdraw bot's EOS 171 | - qu: Read market price(USDT) 172 | - qb: Read market price(BTC) 173 | - b: Balance of bot (USDT & BTC) 174 | - s: Read Snapshots 175 | - tb: Transfer 0.0001 BTC buy USDT 176 | - tu: Transfer $1 USDT buy BTC 177 | - q: Exit 178 | 179 | [Full source code](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/call_apis.php) 180 | 181 | ## Solution Two: List your order on Ocean.One exchange 182 | -------------------------------------------------------------------------------- /README4_Brazilian_Portuguese.md: -------------------------------------------------------------------------------- 1 | 2 | # Como negociar bitcoin através da linguagem PHP 3 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 4 | 5 | ## Solução um: pague para a API ExinCore 6 | [Exincore](https://github.com/exinone/exincore) fornece uma API de negociação comercial na Mixin Network. 7 | 8 | Você paga USDT para a ExinCore, a ExinCore transfere Bitcoin para você na hora com uma taxa bem baixa e um preço justo. Toda transação é anônima para o público mas ainda pode ser verificada no explorer da blockchain. Apenas você e ExinCore sabem os detalhes. 9 | 10 | A ExinCore não sabe quem você é porque a ExinCore sabe apenas seu uuid de cliente. 11 | 12 | ### Pré-requisito 13 | Você deve ter criado um bot baseado na Mixin Network. Crie um lendo [PHP Bitcoin tutorial](https://github.com/wenewzhang/mixin_labs-php-bot). 14 | 15 | #### Instale os pacotes exigidos 16 | Como você sabe, nós apresentamos a você o mixin-sdk-php no [cápitulo 1](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README.md), supondo que foi instalado antes, vamos instalar o **uuid, msgpack** aqui. 17 | ```bash 18 | composer require ramsey/uuid 19 | composer require rybakit/msgpack 20 | ``` 21 | #### Deposite USDT ou Bitcoin na sua conta Mixin Network e leia o saldo 22 | ExinCore pode cambiar entre Bitcoin, USDT, EOS, Eth etc. Aqui te mostra como cambiar entre USDT e Bitcoin, 23 | Verifique o saldo e endereço da carteira antes de fazer a ordem. 24 | 25 | - Verifique o endereço e o saldo, lembre que é um endereço de carteira Bitcoin. 26 | - Deposite Bitcoin neste endereço de carteira Bitcoin. 27 | - Verifique o saldo de Bitcoin após 100 minutos mais tarde. 28 | 29 | **A propósito, o endereço Bitcoin & USDT são os mesmos.** 30 | 31 | ```php 32 | if ($line == '2') { 33 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 34 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 35 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 36 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 37 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 38 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 39 | } 40 | fclose($handle); 41 | } else print("Create user first\n"); 42 | } 43 | if ($line == '3') { 44 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 45 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 46 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 47 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(USDT_ASSET_ID); 48 | print_r("USDT wallet address is :".$asset_info["public_key"]."\n"); 49 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 50 | } 51 | fclose($handle); 52 | } else print("Create user first\n"); 53 | } 54 | ``` 55 | #### Leia o preço de mercado 56 | Como verificar o preço da moeda? Você precisa entender qual é a moeda base. Se você quer comprar Bitcoin e vender USDT, o USDT é a moeda base. Se você quer comprar USDT e vender Bitcoin, o Bitcoin é a moeda base. 57 | ```php 58 | function getExchangeCoins($base_coin) :string { 59 | $client = new GuzzleHttp\Client(); 60 | $res = $client->request('GET', 'https://exinone.com/exincore/markets?base_asset='.$base_coin, [ 61 | ]); 62 | $result = ""; 63 | if ($res->getStatusCode() == "200") { 64 | // echo $res->getStatusCode() . PHP_EOL; 65 | $resInfo = json_decode($res->getBody(), true); 66 | echo "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 67 | $result = "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 68 | foreach ($resInfo["data"] as $key => $coinInfo) { 69 | echo ($coinInfo["exchange_asset"] ." ".$coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 70 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "); 71 | $result .= $coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 72 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "; 73 | foreach ($coinInfo["exchanges"] as $key => $exchange) { 74 | echo $exchange . " "; 75 | $result .= $exchange . " "; 76 | } 77 | echo PHP_EOL; 78 | $result .= PHP_EOL; 79 | } 80 | } 81 | return $result; 82 | } 83 | ``` 84 | 85 | #### Crie um memorando para preparar a ordem 86 | O capítulo dois: [Ecoar Bitcoin](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2.md) apresenta transferência de moedas. Mas você precisa deixar a ExinCore saber qual moeda você quer comprar. Apenas escreva seu ativo alvo no memorando. 87 | ```php 88 | $memo = base64_encode(MessagePack::pack([ 89 | 'A' => Uuid::fromString($_targetAssetID)->getBytes(), 90 | ])); 91 | ``` 92 | #### Pague BTC para a gateway do API como o memorando gerado 93 | Transferir Bitcoin(BTC_ASSET_ID) para ExinCore(EXIN_BOT), coloque seu uuid do ativo alvo no memorando, de outra forma, ExinCore reembolsará a moeda imediatamente! 94 | ```php 95 | const EXIN_BOT = "61103d28-3ac2-44a2-ae34-bd956070dab1"; 96 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 97 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 98 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 99 | coinExchange(BTC_ASSET_ID,"0.0001",USDT_ASSET_ID); 100 | 101 | //........... 102 | 103 | function coinExchange($_assetID,$_amount,$_targetAssetID) { 104 | $mixinSdk = new MixinSDK(require './config.php'); 105 | // print_r(); 106 | $memo = base64_encode(MessagePack::pack([ 107 | 'A' => Uuid::fromString($_targetAssetID)->getBytes(), 108 | ])); 109 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,EXIN_BOT, 110 | $mixinSdk->getConfig()['default']['pin'],$_amount,$memo); 111 | print_r($BotInfo); 112 | } 113 | ``` 114 | A ExinCore deve transferir a moeda alvo para o seu bot, enquanto isso, coloque as informações de taxa, id da ordem, preço e etc. no memorando, descompacte os dados igual abaixo. 115 | - **readUserSnapshots** lê snapshots do usuário. 116 | ```php 117 | $limit = 20; 118 | $offset = '2019-03-10T01:58:25.362528Z'; 119 | $snapInfo = $mixinSdk_BotInstance->Wallet()->readUserSnapshots($limit, $offset); 120 | // print_r($networkInfo2); 121 | foreach ($snapInfo as $record) { 122 | // echo $key . PHP_EOL; 123 | // print_r($record); 124 | if ($record['amount'] > 0 and $record['memo'] != '') { 125 | echo "------------MEMO:-coin--exchange--------------" . PHP_EOL; 126 | echo "memo: " . $record['memo'] . PHP_EOL; 127 | // print_r($dtPay->memo); 128 | echo "You Get Coins: ". $record['asset_id']. " " . $record['amount'] . PHP_EOL; 129 | $memoUnpack = MessagePack::unpack(base64_decode($record['memo'])); 130 | $feeAssetID = Uuid::fromBytes($memoUnpack['FA'])->toString(); 131 | $OrderID = Uuid::fromBytes($memoUnpack['O'])->toString(); 132 | if ($memoUnpack['C'] == 1000) { 133 | echo "Successful Exchange:". PHP_EOL; 134 | echo "Fee asset ID: " . $feeAssetID . " fee is :" . $memoUnpack['F'] . PHP_EOL; 135 | echo "Order ID: " . $OrderID . " Price is :" . $memoUnpack['P'] . PHP_EOL; 136 | } else print_r($memoUnpack); 137 | echo "--------------memo-record end---------------" . PHP_EOL; 138 | } 139 | } 140 | ``` 141 | 142 | Se sua troca de moedas foi um sucesso, a saída do console mostrará o seguinte: 143 | ```bash 144 | ------------MEMO:-coin--exchange-------------- 145 | memo: hqFDzQPooVCnMzg3Mi45N6FGqTAuMDAwNzc0NqJGQcQQgVsLGidkNzaPqkLWlPpiCqFUoUahT8QQIbfeL6p5RVOcEP0mLb+t+g== 146 | You Get Coins: 815b0b1a-2764-3736-8faa-42d694fa620a 0.3857508 147 | Successful Exchange: 148 | Fee asset ID: 815b0b1a-2764-3736-8faa-42d694fa620a fee is :0.0007746 149 | Order ID: 21b7de2f-aa79-4553-9c10-fd262dbfadfa Price is :3872.97 150 | --------------memo-record end--------------- 151 | ``` 152 | 153 | #### Leia o saldo de Bitcoin 154 | Verifique o saldo da carteira. 155 | ```php 156 | $mixinSdk = new MixinSDK(require './config.php'); 157 | $asset_info = $mixinSdk->Wallet()->readAsset(USDT_ASSET_ID); 158 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 159 | ``` 160 | ## Uso do código de fonte 161 | Execute **php call_apis.php** para rodar isto. 162 | 163 | - 1: Criar usuário e atualizar PIN 164 | - 2: Ler o saldo e endereço de Bitcoin 165 | - 3: Ler o saldo e o endereço USDT 166 | - 4: Ler saldo EOS 167 | - 5: Ler endereço EOS 168 | - 6: Transferir Bitcoin do bot para um novo usuário 169 | - 7: Transferir Bitcoin de um novo usuário para Master 170 | - 8: Sacar Bitcoin do bot 171 | - 9: Sacar EOS do bot 172 | - qu: Ler o preço de mercado (USDT) 173 | - qb: Ler o preço de mercado(BTC) 174 | - b: Saldo do bot (USDT & BTC) 175 | - s: Leitura instantânea 176 | - tb: Transferir 0.0001 BTC comprar USDT 177 | - tu: Transferir $1 USDT comprar BTC 178 | - q: Sair 179 | 180 | [Código fonte completo](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/call_apis.php) 181 | 182 | ## Solução dois: Listar sua ordem na exchange Ocean.One 183 | -------------------------------------------------------------------------------- /README5-russian.md: -------------------------------------------------------------------------------- 1 | # Как торговать биткойнами с помощью PHP 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | В [предыдущей, 4-й части](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README4-russian.md) мы дали представление об ExinCore, где можно обменивать многие крипто-активы по курсу и получать свой актив через 1 секунду. Если вы хотите торговать активом по специальной цене или ExinCore его не поддерживает, то вам подойдет OceanOne. 5 | 6 | ## Решение №2: отправьте ордер на биржу Ocean.One 7 | [Ocean.one](https://github.com/mixinNetwork/ocean.one) – это децентрализованная биржа, созданная в Mixin Network. Практически впервые децентрализованная биржа дает пользователям те же возможности, что и централизованная. 8 | 9 | На OceanOne можно торговать любыми активами. Пополните счет на OceanOne активом, который хотите продать, напишите запрос в `memo` платежа, и OceanOne выставит ваш ордер на торги. Актив поступает на ваш кошелек после успешной сделки. 10 | 11 | * Без регистрации 12 | * Без депозита 13 | * Без оформления допуска к торгам 14 | 15 | ### Предварительное условие 16 | Требуется создать бот на базе Mixin Network. Создать его можно, обратившись к [туториалу по PHP для работы с биткойном](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README.md). 17 | 18 | #### Установите необходимые пакеты 19 | В [части 4](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README4.md) мы представляем [**mixin-sdk-php**](https://packagist.org/packages/exinone/mixin-sdk-php). Будем считать, что он уже установлен. 20 | 21 | #### Положите USDT или биткойн на депозит в своей учётной записи Mixin Network и проверьте баланс 22 | Ocean.one может выполнить любой ордер. Мы продемонстрируем обмен USDT на биткойны. Проверьте баланс и адрес кошелька до отправки ордера. 23 | 24 | - Проверьте адрес и баланс, найдите адрес биткойн-кошелька. 25 | - Внесите биткойн на адрес этого биткойн-кошелька. 26 | - Проверьте баланс биткойн-кошелька через 100 минут. 27 | 28 | **Кстати, адреса биткойн и USDT не отличаются.** 29 | 30 | ```php 31 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 32 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 33 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 34 | 35 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 36 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 37 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 38 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 39 | ``` 40 | 41 | #### Проверьте стакан котировок на Ocean.one 42 | Как проверить курс обмена монет? Необходимо понимать, что такое базовая монета. Если вы покупаете биткойн, а продаёте USDT, то базовой монетой будет USDT. Если вы покупаете USDT, а продаёте биткойн, то базовой монетой будет биткойн. 43 | 44 | 45 | ```php 46 | if ( $ocmd == '1') { getOceanOneMarketInfos(XIN_ASSET_ID,USDT_ASSET_ID);} 47 | function getOceanOneMarketInfos($targetCoin, $baseCoin) { 48 | $client = new GuzzleHttp\Client(); 49 | $baseUrl = "https://events.ocean.one/markets/".$targetCoin."-".$baseCoin."/book"; 50 | $res = $client->request('GET', $baseUrl, [ 51 | ]); 52 | if ($res->getStatusCode() == "200") { 53 | // echo $res->getStatusCode() . PHP_EOL; 54 | $resInfo = json_decode($res->getBody(), true); 55 | echo "Side | Price | Amount | Funds" . PHP_EOL; 56 | foreach ($resInfo["data"]["data"]["asks"] as $key => $exchange) { 57 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 58 | } 59 | foreach ($resInfo["data"]["data"]["bids"] as $key => $exchange) { 60 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 61 | } 62 | } 63 | } 64 | ``` 65 | 66 | #### Создайте memo для подготовки ордера 67 | 68 | Во второй части [Возврат биткойна](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2-russian.md) мы рассказывали, как отправить монеты. Но Ocean.one должна знать, какие монеты вы хотите купить. 69 | - переменная `side` может быть `B` или `A`: `B` — если покупаете, `A` — если продаете; 70 | - переменная `asset` — это `UUID` актива, который вы хотите купить; 71 | - переменная `price` работает так: если `side` соответствует `B`, цена указывается в единицах покупаемого актива (`UUID`); если `side` соответствует `A`, цена указывается в единицах актива, переводимого на Ocean.one. 72 | 73 | ```php 74 | function GenerateOrderMemo($side, $asset, $price) :string { 75 | $memo = base64_encode(MessagePack::pack([ 76 | 'S' => $side, 77 | 'A' => Uuid::fromString($asset)->getBytes(), 78 | 'P' => $price, 79 | 'T' => 'L', 80 | ])); 81 | return $memo; 82 | } 83 | ``` 84 | 85 | #### Создайте memo и заплатите биткойнами через OceanOne 86 | Переведите биткойн(BTC_ASSET_ID) на Ocean.one(OCEANONE_BOT), укажите `uuid` нужного актива(USDT) в `memo`. 87 | 88 | ```php 89 | const OCEANONE_BOT = "aaff5bef-42fb-4c9f-90e0-29f69176b7d4"; 90 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 91 | const XIN_ASSET_ID = "c94ac88f-4671-3976-b60a-09064f1811e8"; 92 | 93 | if ( $ocmd == 's1') { 94 | $p = readline("Input the Price of XIN/USDT: "); 95 | $a = readline("Input the Amount of XIN: "); 96 | $tMemo = GenerateOrderMemo("A",USDT_ASSET_ID,$p); 97 | echo $tMemo . PHP_EOL; 98 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 99 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(XIN_ASSET_ID); 100 | print_r($asset_info); 101 | if ( (float) $asset_info["balance"] >= (float) $a ) { 102 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(XIN_ASSET_ID,OCEANONE_BOT, 103 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 104 | $a, 105 | $tMemo); 106 | print_r($transInfos); 107 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 108 | } else { echo "Not enough XIN!\n";} 109 | } 110 | ``` 111 | 112 | Чтобы купить XIN, выполните следующее: 113 | 114 | ```php 115 | if ( $ocmd == 'b1') { 116 | $p = readline("Input the Price of XIN/USDT: "); 117 | $a = readline("Input the Amount of USDT: "); 118 | $tMemo = GenerateOrderMemo("B",XIN_ASSET_ID,$p); 119 | echo $tMemo . PHP_EOL; 120 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 121 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(USDT_ASSET_ID); 122 | 123 | print_r($asset_info); 124 | if ( ((float) $asset_info["balance"] >= 1) && ( (float) $asset_info["balance"] >= (float) $a ) ) { 125 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(USDT_ASSET_ID,OCEANONE_BOT, 126 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 127 | $a, 128 | $tMemo); 129 | print_r($transInfos); 130 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 131 | } else { echo "Not enough USDT!\n";} 132 | } 133 | ``` 134 | 135 | Лог по успешно выполненному ордеру выглядит так: 136 | ```bash 137 | Input the Price of XIN/USDT: 112 138 | Input the Amount of USDT: 1 139 | hKFToUKhQcQQyUrIj0ZxOXa2CgkGTxgR6KFQozExMqFUoUw= 140 | client id is:26b20aa5-40c0-3e00-9de0-666cfb6f2daa 141 | Array 142 | ( 143 | [type] => asset 144 | [asset_id] => 815b0b1a-2764-3736-8faa-42d694fa620a 145 | [chain_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa 146 | [symbol] => USDT 147 | [name] => Tether USD 148 | [icon_url] => https://images.mixin.one/ndNBEpObYs7450U08oAOMnSEPzN66SL8Mh-f2pPWBDeWaKbXTPUIdrZph7yj8Z93Rl8uZ16m7Qjz-E-9JFKSsJ-F=s128 149 | [balance] => 1 150 | [public_key] => 17z1Rq3VsyvvXvGWiHT8YErjBoFgnhErB8 151 | [account_name] => 152 | [account_tag] => 153 | [price_btc] => 0,00019038 154 | [price_usd] => 1.00036293 155 | [change_btc] => 0.013486479778200063 156 | [change_usd] => 0.005376748815937048 157 | [asset_key] => 815b0b1a-2764-3736-8faa-42d694fa620a 158 | [confirmations] => 6 159 | [capitalization] => 0 160 | ) 161 | Array 162 | ( 163 | [type] => transfer 164 | [snapshot_id] => f4b1f8d6-004a-4d2b-997d-4d0acf1096cd 165 | [opponent_id] => aaff5bef-42fb-4c9f-90e0-29f69176b7d4 166 | [asset_id] => 815b0b1a-2764-3736-8faa-42d694fa620a 167 | [amount] => -1 168 | [trace_id] => b12eed67-6cf4-481f-b25b-dd41f28e1984 169 | [memo] => hKFToUKhQcQQyUrIj0ZxOXa2CgkGTxgR6KFQozExMqFUoUw= 170 | [created_at] => 2019-04-30T01:17:02.206240549Z 171 | [counter_user_id] => aaff5bef-42fb-4c9f-90e0-29f69176b7d4 172 | ) 173 | The Order ID (trace_id) is: b12eed67-6cf4-481f-b25b-dd41f28e1984 174 | ``` 175 | ## Как отменить ордер 176 | Чтобы отменить ордер, просто заплатите любую сумму любого актива на OceanOne и напишите `trace_id` в `memo`. Для Ocean.one это будет идентификатор ордера, например, **b12eed67-6cf4-481f-b25b-dd41f28e1984**, 177 | С его помощью можно отменить ордер. 178 | 179 | ```php 180 | if ( $ocmd == 'c' ) { 181 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 182 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(CNB_ASSET_ID); 183 | if ( ((float) $asset_info["balance"] == 0) ) { 184 | echo "Please deposit some CNB to this Wallet!" . PHP_EOL; 185 | } else { 186 | $orderid = readline("Input the Order id ( trace_id ): "); 187 | $cMemo = base64_encode(MessagePack::pack([ 188 | 'O' => Uuid::fromString($orderid)->getBytes(), 189 | ])); 190 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(CNB_ASSET_ID,OCEANONE_BOT, 191 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 192 | "0.00000001", 193 | $cMemo); 194 | print_r($transInfos); 195 | } 196 | } 197 | ``` 198 | #### Проверьте баланс биткойна 199 | Проверьте и отобразите баланс кошелька. 200 | ```php 201 | if ($line == 'aw') { 202 | $mixinSdk_eachAccountInstance = GenerateWalletSDKFromCSV(); 203 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAssets(); 204 | foreach ($asset_info as $key => $asset) { 205 | echo $asset["symbol"] . " " . $asset["asset_id"] ." ". $asset["balance"] . 206 | " ". $asset["public_key"].PHP_EOL; 207 | } 208 | } 209 | ``` 210 | 211 | ## Как пользоваться исходным кодом 212 | Создайте и запустите его. 213 | 214 | - запустите команду **php bitcoin_wallet.php**. 215 | 216 | Команды для ведения торгов на OceanOne: 217 | 218 | - o: Ocean.One Exchange 219 | - q: Exit («Выйти») 220 | 221 | Make your choose(eg: q for Exit!): 222 | 223 | - 1: Fetch XIN/USDT orders 224 | - s1: Sell XIN/USDT 225 | - b1: Buy XIN/USDT 226 | - 2: Fetch ERC20(Benz)/USDT orders 227 | - s2: Sell Benz/USDT 228 | - b2: Buy Benz/USDT 229 | - q: Exit 230 | 231 | [Исходный код полностью](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/bitcoin_wallet.php) 232 | 233 | -------------------------------------------------------------------------------- /README5-zhchs.md: -------------------------------------------------------------------------------- 1 | # 通过 PHP 买卖Bitcoin 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 上一章介绍了[Exincore](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README4-zhchs.md),你可以1秒完成资产的市价买卖。如果你想限定价格买卖,或者买卖一些exincore不支持的资产,你需要OceanOne。 4 | 5 | ## 方案二: 挂单Ocean.One交易所 6 | [Ocean.one](https://github.com/mixinNetwork/ocean.one)是基于Mixin Network的去中心化交易所,它性能一流。 7 | 你可以在OceanOne上交易任何资产,只需要将你的币转给OceanOne, 将交易信息写在交易的memo里,OceanOne会在市场里列出你的交易需求, 8 | 交易成功后,会将目标币转入到你的MixinNetwork帐上,它有三大特点与优势: 9 | - 不需要在OceanOne注册 10 | - 不需要存币到交易所 11 | - 支持所有Mixin Network上能够转账的资产,所有的ERC20 EOS代币。 12 | 13 | ### 预备知识: 14 | 你先需要创建一个机器人, 方法在 [教程一](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README-zhchs.md). 15 | 16 | #### 安装依赖包 17 | 正如教程一里我们介绍过的, 我们需要依赖 [**mixin-sdk-php**](https://packagist.org/packages/exinone/mixin-sdk-php), 你应该已经先安装过它了. 18 | 19 | #### 安装依赖的库 20 | [第四课](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README4-zhchs.md), 在上一课中已经安装好了. 21 | 22 | #### 充币到 Mixin Network, 并读出它的余额. 23 | 此处演示用 USDT购买BTC 或者 用BTC购买USDT。交易前,先检查一下钱包地址。 24 | 完整的步骤如下: 25 | - 检查比特币或USDT的余额,钱包地址。并记下钱包地址。 26 | - 从第三方交易所或者你的冷钱包中,将币充到上述钱包地址。 27 | - 再检查一下币的余额,看到帐与否。(比特币的到帐时间是5个区块的高度,约100分钟)。 28 | 29 | 比特币与USDT的充值地址是一样的。 30 | 31 | ```php 32 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 33 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 34 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 35 | 36 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 37 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 38 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 39 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 40 | ``` 41 | 42 | #### 取得Ocean.one的市场价格信息 43 | 如何来查询Ocean.one市场的价格信息呢?你要先了解你交易的基础币是什么,如果你想买比特币,卖出USDT,那么基础货币就是USDT;如果你想买USDT,卖出比特币,那么基础货币就是比特币. 44 | 45 | ```php 46 | if ( $ocmd == '1') { getOceanOneMarketInfos(XIN_ASSET_ID,USDT_ASSET_ID);} 47 | function getOceanOneMarketInfos($targetCoin, $baseCoin) { 48 | $client = new GuzzleHttp\Client(); 49 | $baseUrl = "https://events.ocean.one/markets/".$targetCoin."-".$baseCoin."/book"; 50 | $res = $client->request('GET', $baseUrl, [ 51 | ]); 52 | if ($res->getStatusCode() == "200") { 53 | // echo $res->getStatusCode() . PHP_EOL; 54 | $resInfo = json_decode($res->getBody(), true); 55 | echo "Side | Price | Amount | Funds" . PHP_EOL; 56 | foreach ($resInfo["data"]["data"]["asks"] as $key => $exchange) { 57 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 58 | } 59 | foreach ($resInfo["data"]["data"]["bids"] as $key => $exchange) { 60 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 61 | } 62 | } 63 | } 64 | ``` 65 | 66 | #### 交易前,创建一个Memo! 67 | 在第二章里,[基于Mixin Network的 PHP 比特币开发教程: 机器人接受比特币并立即退还用户](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2-zhchs.md), 我们学习过转帐,这儿我们介绍如何告诉Ocean.one,我们给它转帐的目的是什么,信息全部放在memo里. 68 | - **side** 方向,"B" 或者 "A", "B"是购买, "A"是出售. 69 | - **asset** 目标虚拟资产的UUID. 70 | - **price** 价格,如果操作方向是"B", 价格就是AssetUUID的价格; 如果操作方向是"B", 价格就是转给Ocean.one币的价格. 71 | 72 | ```php 73 | function GenerateOrderMemo($side, $asset, $price) :string { 74 | $memo = base64_encode(MessagePack::pack([ 75 | 'S' => $side, 76 | 'A' => Uuid::fromString($asset)->getBytes(), 77 | 'P' => $price, 78 | 'T' => 'L', 79 | ])); 80 | return $memo; 81 | } 82 | ``` 83 | 84 | #### 出售XIN的例子 85 | 转打算出售的XIN给Ocean.one(OCEANONE_BOT),将你打算换回来的目标虚拟资产的UUID放入memo. 86 | 87 | ```php 88 | const OCEANONE_BOT = "aaff5bef-42fb-4c9f-90e0-29f69176b7d4"; 89 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 90 | const XIN_ASSET_ID = "c94ac88f-4671-3976-b60a-09064f1811e8"; 91 | 92 | if ( $ocmd == 's1') { 93 | $p = readline("Input the Price of XIN/USDT: "); 94 | $a = readline("Input the Amount of XIN: "); 95 | $tMemo = GenerateOrderMemo("A",USDT_ASSET_ID,$p); 96 | echo $tMemo . PHP_EOL; 97 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 98 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(XIN_ASSET_ID); 99 | print_r($asset_info); 100 | if ( (float) $asset_info["balance"] >= (float) $a ) { 101 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(XIN_ASSET_ID,OCEANONE_BOT, 102 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 103 | $a, 104 | $tMemo); 105 | print_r($transInfos); 106 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 107 | } else { echo "Not enough XIN!\n";} 108 | } 109 | ``` 110 | 如果你是打算买XIN,操作如下: 111 | 112 | ```php 113 | if ( $ocmd == 'b1') { 114 | $p = readline("Input the Price of XIN/USDT: "); 115 | $a = readline("Input the Amount of USDT: "); 116 | $tMemo = GenerateOrderMemo("B",XIN_ASSET_ID,$p); 117 | echo $tMemo . PHP_EOL; 118 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 119 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(USDT_ASSET_ID); 120 | 121 | print_r($asset_info); 122 | if ( ((float) $asset_info["balance"] >= 1) && ( (float) $asset_info["balance"] >= (float) $a ) ) { 123 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(USDT_ASSET_ID,OCEANONE_BOT, 124 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 125 | $a, 126 | $tMemo); 127 | print_r($transInfos); 128 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 129 | } else { echo "Not enough USDT!\n";} 130 | } 131 | ``` 132 | 133 | 一个成功的挂单如下: 134 | ```bash 135 | Input the Price of XIN/USDT: 112 136 | Input the Amount of USDT: 1 137 | hKFToUKhQcQQyUrIj0ZxOXa2CgkGTxgR6KFQozExMqFUoUw= 138 | client id is:26b20aa5-40c0-3e00-9de0-666cfb6f2daa 139 | Array 140 | ( 141 | [type] => asset 142 | [asset_id] => 815b0b1a-2764-3736-8faa-42d694fa620a 143 | [chain_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa 144 | [symbol] => USDT 145 | [name] => Tether USD 146 | [icon_url] => https://images.mixin.one/ndNBEpObYs7450U08oAOMnSEPzN66SL8Mh-f2pPWBDeWaKbXTPUIdrZph7yj8Z93Rl8uZ16m7Qjz-E-9JFKSsJ-F=s128 147 | [balance] => 1 148 | [public_key] => 17z1Rq3VsyvvXvGWiHT8YErjBoFgnhErB8 149 | [account_name] => 150 | [account_tag] => 151 | [price_btc] => 0.00019038 152 | [price_usd] => 1.00036293 153 | [change_btc] => 0.013486479778200063 154 | [change_usd] => 0.005376748815937048 155 | [asset_key] => 815b0b1a-2764-3736-8faa-42d694fa620a 156 | [confirmations] => 6 157 | [capitalization] => 0 158 | ) 159 | Array 160 | ( 161 | [type] => transfer 162 | [snapshot_id] => f4b1f8d6-004a-4d2b-997d-4d0acf1096cd 163 | [opponent_id] => aaff5bef-42fb-4c9f-90e0-29f69176b7d4 164 | [asset_id] => 815b0b1a-2764-3736-8faa-42d694fa620a 165 | [amount] => -1 166 | [trace_id] => b12eed67-6cf4-481f-b25b-dd41f28e1984 167 | [memo] => hKFToUKhQcQQyUrIj0ZxOXa2CgkGTxgR6KFQozExMqFUoUw= 168 | [created_at] => 2019-04-30T01:17:02.206240549Z 169 | [counter_user_id] => aaff5bef-42fb-4c9f-90e0-29f69176b7d4 170 | ) 171 | The Order ID (trace_id) is: b12eed67-6cf4-481f-b25b-dd41f28e1984 172 | ``` 173 | #### 取消挂单 174 | Ocean.one将trace_id当做订单,比如上面的例子, **b12eed67-6cf4-481f-b25b-dd41f28e1984** 就是订单号,我们用他来取消订单。 175 | 176 | ```php 177 | if ( $ocmd == 'c' ) { 178 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 179 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(CNB_ASSET_ID); 180 | if ( ((float) $asset_info["balance"] == 0) ) { 181 | echo "Please deposit some CNB to this Wallet!" . PHP_EOL; 182 | } else { 183 | $orderid = readline("Input the Order id ( trace_id ): "); 184 | $cMemo = base64_encode(MessagePack::pack([ 185 | 'O' => Uuid::fromString($orderid)->getBytes(), 186 | ])); 187 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(CNB_ASSET_ID,OCEANONE_BOT, 188 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 189 | "0.00000001", 190 | $cMemo); 191 | print_r($transInfos); 192 | } 193 | } 194 | ``` 195 | #### 通过读取资产余额,来确认到帐情况 196 | Check the wallet's balance. 197 | ```php 198 | if ($line == 'aw') { 199 | $mixinSdk_eachAccountInstance = GenerateWalletSDKFromCSV(); 200 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAssets(); 201 | foreach ($asset_info as $key => $asset) { 202 | echo $asset["symbol"] . " " . $asset["asset_id"] ." ". $asset["balance"] . 203 | " ". $asset["public_key"].PHP_EOL; 204 | } 205 | } 206 | ``` 207 | 208 | ## 源代码执行 209 | 运行就可以开始交易了. 210 | 211 | - **php bitcoin_wallet.php** 运行项目 212 | 213 | 本代码执行时的命令列表: 214 | 215 | - o: Ocean.One Exchange 216 | - q: Exit 217 | 218 | Make your choose(eg: q for Exit!): 219 | 220 | - 1: Fetch XIN/USDT orders 221 | - s1: Sell XIN/USDT 222 | - b1: Buy XIN/USDT 223 | - 2: Fetch ERC20(Benz)/USDT orders 224 | - s2: Sell Benz/USDT 225 | - b2: Buy Benz/USDT 226 | - q: Exit 227 | 228 | [完整代码](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/bitcoin_wallet.php) 229 | -------------------------------------------------------------------------------- /README5.md: -------------------------------------------------------------------------------- 1 | # How to trade bitcoin through PHP 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 3 | 4 | Exincore is introduced in [last chapter](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README4.md), you can exchange many crypto asset at market price and receive your asset in 1 seconds. If you want to trade asset at limited price, or trade asset is not supported by ExinCore now, OceanOne is the answer. 5 | 6 | ## Solution Two: List your order on Ocean.One exchange 7 | [Ocean.one](https://github.com/mixinNetwork/ocean.one) is a decentralized exchange built on Mixin Network, it's almost the first time that a decentralized exchange gain the same user experience as a centralized one. 8 | 9 | You can list any asset on OceanOne. Pay the asset you want to sell to OceanOne account, write your request in payment memo, OceanOne will list your order to market. It send asset to your wallet after your order is matched. 10 | 11 | * No sign up required 12 | * No deposit required 13 | * No listing process. 14 | 15 | ### Pre-request: 16 | You should have created a bot based on Mixin Network. Create one by reading [PHP Bitcoin tutorial](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README.md). 17 | 18 | #### Install required packages 19 | [Chapter 4](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README4.md) introduce [**mixin-sdk-php**](https://packagist.org/packages/exinone/mixin-sdk-php) to you, assume it has installed before. 20 | 21 | #### Deposit USDT or Bitcoin into your Mixin Network account and read balance 22 | The Ocean.one can match any order. Here we exchange between USDT and Bitcoin, Check the wallet's balance & address before you make order. 23 | 24 | - Check the address & balance, find it's Bitcoin wallet address. 25 | - Deposit Bitcoin to this Bitcoin wallet address. 26 | - Check Bitcoin balance after 100 minutes later. 27 | 28 | **Omni USDT address is same as Bitcoin address** 29 | 30 | ```php 31 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 32 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 33 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 34 | 35 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 36 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 37 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 38 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 39 | ``` 40 | 41 | #### Read orders book from Ocean.one 42 | How to check the coin's price? You need understand what is the base coin. If you want buy Bitcoin and sell USDT, the USDT is the base coin. If you want buy USDT and sell Bitcoin, the Bitcoin is the base coin. 43 | 44 | 45 | ```php 46 | if ( $ocmd == '1') { getOceanOneMarketInfos(XIN_ASSET_ID,USDT_ASSET_ID);} 47 | function getOceanOneMarketInfos($targetCoin, $baseCoin) { 48 | $client = new GuzzleHttp\Client(); 49 | $baseUrl = "https://events.ocean.one/markets/".$targetCoin."-".$baseCoin."/book"; 50 | $res = $client->request('GET', $baseUrl, [ 51 | ]); 52 | if ($res->getStatusCode() == "200") { 53 | // echo $res->getStatusCode() . PHP_EOL; 54 | $resInfo = json_decode($res->getBody(), true); 55 | echo "Side | Price | Amount | Funds" . PHP_EOL; 56 | foreach ($resInfo["data"]["data"]["asks"] as $key => $exchange) { 57 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 58 | } 59 | foreach ($resInfo["data"]["data"]["bids"] as $key => $exchange) { 60 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 61 | } 62 | } 63 | } 64 | ``` 65 | 66 | #### Create a memo to prepare order 67 | The chapter two: [Echo Bitcoin](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2.md) introduce transfer coins. But you need to let Ocean.one know which coin you want to buy. 68 | - **side** "B" or "A", "B" for buy, "A" for Sell. 69 | - **asset** UUID of the asset you want to buy 70 | - **price** If Side is "B", Price is AssetUUID; if Side is "A", Price is the asset which transfer to Ocean.one. 71 | 72 | ```php 73 | function GenerateOrderMemo($side, $asset, $price) :string { 74 | $memo = base64_encode(MessagePack::pack([ 75 | 'S' => $side, 76 | 'A' => Uuid::fromString($asset)->getBytes(), 77 | 'P' => $price, 78 | 'T' => 'L', 79 | ])); 80 | return $memo; 81 | } 82 | ``` 83 | 84 | #### Pay BTC to OceanOne with generated memo 85 | Transfer Bitcoin(BTC_ASSET_ID) to Ocean.one(OCEANONE_BOT), put you target asset uuid(USDT) in the memo. 86 | 87 | ```php 88 | const OCEANONE_BOT = "aaff5bef-42fb-4c9f-90e0-29f69176b7d4"; 89 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 90 | const XIN_ASSET_ID = "c94ac88f-4671-3976-b60a-09064f1811e8"; 91 | 92 | if ( $ocmd == 's1') { 93 | $p = readline("Input the Price of XIN/USDT: "); 94 | $a = readline("Input the Amount of XIN: "); 95 | $tMemo = GenerateOrderMemo("A",USDT_ASSET_ID,$p); 96 | echo $tMemo . PHP_EOL; 97 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 98 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(XIN_ASSET_ID); 99 | print_r($asset_info); 100 | if ( (float) $asset_info["balance"] >= (float) $a ) { 101 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(XIN_ASSET_ID,OCEANONE_BOT, 102 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 103 | $a, 104 | $tMemo); 105 | print_r($transInfos); 106 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 107 | } else { echo "Not enough XIN!\n";} 108 | } 109 | ``` 110 | 111 | If you want buy XIN, call it like below: 112 | 113 | ```php 114 | if ( $ocmd == 'b1') { 115 | $p = readline("Input the Price of XIN/USDT: "); 116 | $a = readline("Input the Amount of USDT: "); 117 | $tMemo = GenerateOrderMemo("B",XIN_ASSET_ID,$p); 118 | echo $tMemo . PHP_EOL; 119 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 120 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(USDT_ASSET_ID); 121 | 122 | print_r($asset_info); 123 | if ( ((float) $asset_info["balance"] >= 1) && ( (float) $asset_info["balance"] >= (float) $a ) ) { 124 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(USDT_ASSET_ID,OCEANONE_BOT, 125 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 126 | $a, 127 | $tMemo); 128 | print_r($transInfos); 129 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 130 | } else { echo "Not enough USDT!\n";} 131 | } 132 | ``` 133 | 134 | A success order output like below: 135 | ```bash 136 | Input the Price of XIN/USDT: 112 137 | Input the Amount of USDT: 1 138 | hKFToUKhQcQQyUrIj0ZxOXa2CgkGTxgR6KFQozExMqFUoUw= 139 | client id is:26b20aa5-40c0-3e00-9de0-666cfb6f2daa 140 | Array 141 | ( 142 | [type] => asset 143 | [asset_id] => 815b0b1a-2764-3736-8faa-42d694fa620a 144 | [chain_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa 145 | [symbol] => USDT 146 | [name] => Tether USD 147 | [icon_url] => https://images.mixin.one/ndNBEpObYs7450U08oAOMnSEPzN66SL8Mh-f2pPWBDeWaKbXTPUIdrZph7yj8Z93Rl8uZ16m7Qjz-E-9JFKSsJ-F=s128 148 | [balance] => 1 149 | [public_key] => 17z1Rq3VsyvvXvGWiHT8YErjBoFgnhErB8 150 | [account_name] => 151 | [account_tag] => 152 | [price_btc] => 0.00019038 153 | [price_usd] => 1.00036293 154 | [change_btc] => 0.013486479778200063 155 | [change_usd] => 0.005376748815937048 156 | [asset_key] => 815b0b1a-2764-3736-8faa-42d694fa620a 157 | [confirmations] => 6 158 | [capitalization] => 0 159 | ) 160 | Array 161 | ( 162 | [type] => transfer 163 | [snapshot_id] => f4b1f8d6-004a-4d2b-997d-4d0acf1096cd 164 | [opponent_id] => aaff5bef-42fb-4c9f-90e0-29f69176b7d4 165 | [asset_id] => 815b0b1a-2764-3736-8faa-42d694fa620a 166 | [amount] => -1 167 | [trace_id] => b12eed67-6cf4-481f-b25b-dd41f28e1984 168 | [memo] => hKFToUKhQcQQyUrIj0ZxOXa2CgkGTxgR6KFQozExMqFUoUw= 169 | [created_at] => 2019-04-30T01:17:02.206240549Z 170 | [counter_user_id] => aaff5bef-42fb-4c9f-90e0-29f69176b7d4 171 | ) 172 | The Order ID (trace_id) is: b12eed67-6cf4-481f-b25b-dd41f28e1984 173 | ``` 174 | ## Cancel the Order 175 | To cancel order, just pay any amount of any asset to OceanOne, and write trace_id into memo. Ocean.one take the trace_id as the order id, for example, **b12eed67-6cf4-481f-b25b-dd41f28e1984** is a order id, 176 | We can use it to cancel the order. 177 | 178 | ```php 179 | if ( $ocmd == 'c' ) { 180 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 181 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(CNB_ASSET_ID); 182 | if ( ((float) $asset_info["balance"] == 0) ) { 183 | echo "Please deposit some CNB to this Wallet!" . PHP_EOL; 184 | } else { 185 | $orderid = readline("Input the Order id ( trace_id ): "); 186 | $cMemo = base64_encode(MessagePack::pack([ 187 | 'O' => Uuid::fromString($orderid)->getBytes(), 188 | ])); 189 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(CNB_ASSET_ID,OCEANONE_BOT, 190 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 191 | "0.00000001", 192 | $cMemo); 193 | print_r($transInfos); 194 | } 195 | } 196 | ``` 197 | #### Read Bitcoin balance 198 | Check the wallet's balance. 199 | ```php 200 | if ($line == 'aw') { 201 | $mixinSdk_eachAccountInstance = GenerateWalletSDKFromCSV(); 202 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAssets(); 203 | foreach ($asset_info as $key => $asset) { 204 | echo $asset["symbol"] . " " . $asset["asset_id"] ." ". $asset["balance"] . 205 | " ". $asset["public_key"].PHP_EOL; 206 | } 207 | } 208 | ``` 209 | 210 | ## Source code usage 211 | Build it and then run it. 212 | 213 | - **php bitcoin_wallet.php** run it. 214 | 215 | Commands of trade with OceanOne: 216 | 217 | - o: Ocean.One Exchange 218 | - q: Exit 219 | 220 | Make your choose(eg: q for Exit!): 221 | 222 | - 1: Fetch XIN/USDT orders 223 | - s1: Sell XIN/USDT 224 | - b1: Buy XIN/USDT 225 | - 2: Fetch ERC20(Benz)/USDT orders 226 | - s2: Sell Benz/USDT 227 | - b2: Buy Benz/USDT 228 | - q: Exit 229 | 230 | [Full source code](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/bitcoin_wallet.php) 231 | -------------------------------------------------------------------------------- /README5_Brazilian_Portuguese.md: -------------------------------------------------------------------------------- 1 | 2 | # Como negociar bitcoin através de PHP 3 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/Bitcoin_php.jpg) 4 | 5 | Exincore foi introduzido no [último capítulo](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README4.md), você pode trocar muitos cripto ativos a preço de mercado e receber seu ativo em 1 segundo. Se você quer negociar ativos a um preço limitado, ou negociar ativos não suportados pela ExinCore no momento, OceanOne é a resposta. 6 | 7 | ## Solução Dois: Liste sua ordem na Ocean.One exchange 8 | [Ocean.one](https://github.com/mixinNetwork/ocean.one) é uma exchange descentralizada construída na Mixin Network, é quase a primeira vez que uma exchange descentralizada obtêm a mesma experiência de usuário do que uma centralizada. 9 | 10 | Você pode listar qualquer ativo na OceanOne. Pague o ativo que você quer vender para a conta OceanOne, escreva seu pedido no memo de pagamento, OceanOne listará sua ordem no mercado. Ela enviará o ativo para sua carteira após que sua ordem for correspondida. 11 | 12 | * Não é necessário cadastro 13 | * Não é necessário depósito. 14 | * Sem processo de listagem. 15 | 16 | ### Pré-requisito: 17 | Você deve ter criado um bot baseado na Mixin Network. Crie um lendo [PHP Bitcoin tutorial](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README.md). 18 | 19 | #### Instale pacotes necessários 20 | [Capítulo 4](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README4.md) apresenta [**mixin-sdk-php**](https://packagist.org/packages/exinone/mixin-sdk-php) para você, assumindo que foi instalado antes. 21 | 22 | #### Deposite USDT ou Bitcoin na sua conta Mixin Network e leia o saldo 23 | A Ocean.one pode corresponder qualquer ordem. Aqui nós cambiamos entre USDT e Bitcoin, Cheque o saldo da carteira & endereço antes de você fazer a ordem. 24 | 25 | - Cheque o endereço e saldo, ache seu endereço de carteira Bitcoin. 26 | - Deposite Bitcoin nesse endereço de carteira Bitcoin. 27 | - Cheque o saldo de Bitcoin após 100 minutos ou mais. 28 | 29 | **O endereço Omni USDT é o mesmo que o endereço Bitcoin** 30 | 31 | ```php 32 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 33 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 34 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 35 | 36 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 37 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 38 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 39 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 40 | ``` 41 | 42 | #### Leia o livro de ordens da Ocean.one 43 | Como verificar o preço da moeda? Você precisa entender qual é a moeda base. Se você quer comprar Bitcoin e vender USDT, o USDT é a moeda base. Se você quer comprar USDT e vender Bitcoin, o Bitcoin é a moeda base. 44 | 45 | 46 | ```php 47 | if ( $ocmd == '1') { getOceanOneMarketInfos(XIN_ASSET_ID,USDT_ASSET_ID);} 48 | function getOceanOneMarketInfos($targetCoin, $baseCoin) { 49 | $client = new GuzzleHttp\Client(); 50 | $baseUrl = "https://events.ocean.one/markets/".$targetCoin."-".$baseCoin."/book"; 51 | $res = $client->request('GET', $baseUrl, [ 52 | ]); 53 | if ($res->getStatusCode() == "200") { 54 | // echo $res->getStatusCode() . PHP_EOL; 55 | $resInfo = json_decode($res->getBody(), true); 56 | echo "Side | Price | Amount | Funds" . PHP_EOL; 57 | foreach ($resInfo["data"]["data"]["asks"] as $key => $exchange) { 58 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 59 | } 60 | foreach ($resInfo["data"]["data"]["bids"] as $key => $exchange) { 61 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 62 | } 63 | } 64 | } 65 | ``` 66 | 67 | #### Crie um memo para preparar a ordem 68 | O capítulo dois: [Echo Bitcoin](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README2.md) apresenta transferência de moedas. Mas você precisa deixar a Ocean.one saber qual moeda você deseja comprar. 69 | - **side** "B" ou "A", "B" para compra, "A" para Venda. 70 | - **asset** UUID do ativo que você quer comprar 71 | - **price** Se Side é "B", Price é AssetUUID; se Side é "A", Price é o ativo que transfere para a Ocean.one. 72 | 73 | ```php 74 | function GenerateOrderMemo($side, $asset, $price) :string { 75 | $memo = base64_encode(MessagePack::pack([ 76 | 'S' => $side, 77 | 'A' => Uuid::fromString($asset)->getBytes(), 78 | 'P' => $price, 79 | 'T' => 'L', 80 | ])); 81 | return $memo; 82 | } 83 | ``` 84 | 85 | #### Pague BTC para a OceanOne com o memo gerado 86 | Transfira Bitcoin(BTC_ASSET_ID) para a Ocean.one(OCEANONE_BOT), coloque seu ativo alvo uuid(USDT) no memo. 87 | 88 | ```php 89 | const OCEANONE_BOT = "aaff5bef-42fb-4c9f-90e0-29f69176b7d4"; 90 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 91 | const XIN_ASSET_ID = "c94ac88f-4671-3976-b60a-09064f1811e8"; 92 | 93 | if ( $ocmd == 's1') { 94 | $p = readline("Input the Price of XIN/USDT: "); 95 | $a = readline("Input the Amount of XIN: "); 96 | $tMemo = GenerateOrderMemo("A",USDT_ASSET_ID,$p); 97 | echo $tMemo . PHP_EOL; 98 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 99 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(XIN_ASSET_ID); 100 | print_r($asset_info); 101 | if ( (float) $asset_info["balance"] >= (float) $a ) { 102 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(XIN_ASSET_ID,OCEANONE_BOT, 103 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 104 | $a, 105 | $tMemo); 106 | print_r($transInfos); 107 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 108 | } else { echo "Not enough XIN!\n";} 109 | } 110 | ``` 111 | 112 | Se você quer comprar XIN, chame-o como abaixo: 113 | 114 | ```php 115 | if ( $ocmd == 'b1') { 116 | $p = readline("Input the Price of XIN/USDT: "); 117 | $a = readline("Input the Amount of USDT: "); 118 | $tMemo = GenerateOrderMemo("B",XIN_ASSET_ID,$p); 119 | echo $tMemo . PHP_EOL; 120 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 121 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(USDT_ASSET_ID); 122 | 123 | print_r($asset_info); 124 | if ( ((float) $asset_info["balance"] >= 1) && ( (float) $asset_info["balance"] >= (float) $a ) ) { 125 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(USDT_ASSET_ID,OCEANONE_BOT, 126 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 127 | $a, 128 | $tMemo); 129 | print_r($transInfos); 130 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 131 | } else { echo "Not enough USDT!\n";} 132 | } 133 | ``` 134 | 135 | Uma ordem bem sucedida tem a saída conforme abaixo: 136 | ```bash 137 | Input the Price of XIN/USDT: 112 138 | Input the Amount of USDT: 1 139 | hKFToUKhQcQQyUrIj0ZxOXa2CgkGTxgR6KFQozExMqFUoUw= 140 | client id is:26b20aa5-40c0-3e00-9de0-666cfb6f2daa 141 | Array 142 | ( 143 | [type] => asset 144 | [asset_id] => 815b0b1a-2764-3736-8faa-42d694fa620a 145 | [chain_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa 146 | [symbol] => USDT 147 | [name] => Tether USD 148 | [icon_url] => https://images.mixin.one/ndNBEpObYs7450U08oAOMnSEPzN66SL8Mh-f2pPWBDeWaKbXTPUIdrZph7yj8Z93Rl8uZ16m7Qjz-E-9JFKSsJ-F=s128 149 | [balance] => 1 150 | [public_key] => 17z1Rq3VsyvvXvGWiHT8YErjBoFgnhErB8 151 | [account_name] => 152 | [account_tag] => 153 | [price_btc] => 0.00019038 154 | [price_usd] => 1.00036293 155 | [change_btc] => 0.013486479778200063 156 | [change_usd] => 0.005376748815937048 157 | [asset_key] => 815b0b1a-2764-3736-8faa-42d694fa620a 158 | [confirmations] => 6 159 | [capitalization] => 0 160 | ) 161 | Array 162 | ( 163 | [type] => transfer 164 | [snapshot_id] => f4b1f8d6-004a-4d2b-997d-4d0acf1096cd 165 | [opponent_id] => aaff5bef-42fb-4c9f-90e0-29f69176b7d4 166 | [asset_id] => 815b0b1a-2764-3736-8faa-42d694fa620a 167 | [amount] => -1 168 | [trace_id] => b12eed67-6cf4-481f-b25b-dd41f28e1984 169 | [memo] => hKFToUKhQcQQyUrIj0ZxOXa2CgkGTxgR6KFQozExMqFUoUw= 170 | [created_at] => 2019-04-30T01:17:02.206240549Z 171 | [counter_user_id] => aaff5bef-42fb-4c9f-90e0-29f69176b7d4 172 | ) 173 | The Order ID (trace_id) is: b12eed67-6cf4-481f-b25b-dd41f28e1984 174 | ``` 175 | ## Cancelar a ordem 176 | Para cancelar uma ordem, apenas pague qualquer quantidade de qualquer ativo para a OceanOne, e escreva trace_id no memo. Ocean.one pega o trace_id como o id da ordem, por exemplo, **b12eed67-6cf4-481f-b25b-dd41f28e1984** é um id de ordem, 177 | Nós podemos usá-lo para cancelar a ordem. 178 | 179 | ```php 180 | if ( $ocmd == 'c' ) { 181 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 182 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(CNB_ASSET_ID); 183 | if ( ((float) $asset_info["balance"] == 0) ) { 184 | echo "Please deposit some CNB to this Wallet!" . PHP_EOL; 185 | } else { 186 | $orderid = readline("Input the Order id ( trace_id ): "); 187 | $cMemo = base64_encode(MessagePack::pack([ 188 | 'O' => Uuid::fromString($orderid)->getBytes(), 189 | ])); 190 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(CNB_ASSET_ID,OCEANONE_BOT, 191 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 192 | "0.00000001", 193 | $cMemo); 194 | print_r($transInfos); 195 | } 196 | } 197 | ``` 198 | #### Leia o saldo de Bitcoin 199 | Cheque o saldo da carteira 200 | ```php 201 | if ($line == 'aw') { 202 | $mixinSdk_eachAccountInstance = GenerateWalletSDKFromCSV(); 203 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAssets(); 204 | foreach ($asset_info as $key => $asset) { 205 | echo $asset["symbol"] . " " . $asset["asset_id"] ." ". $asset["balance"] . 206 | " ". $asset["public_key"].PHP_EOL; 207 | } 208 | } 209 | ``` 210 | 211 | ## Uso do código fonte 212 | Construa e execute-o 213 | 214 | - **php bitcoin_wallet.php** run it. 215 | 216 | Comandos de negociação com a OceanOne: 217 | 218 | - o: Ocean.One Exchange 219 | - q: Sair 220 | 221 | Faça sua escolha(eg: q para Sair!): 222 | 223 | - 1: Buscar ordens de XIN/USDT 224 | - s1: Vender XIN/USDT 225 | - b1: Comprar XIN/USDT 226 | - 2: Buscar ordens ERC20(Benz)/USDT 227 | - s2: Vender Benz/USDT 228 | - b2: Comprar Benz/USDT 229 | - q: Sair 230 | 231 | [Código fonte completo](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/bitcoin_wallet.php) 232 | -------------------------------------------------------------------------------- /README6-zhchs.md: -------------------------------------------------------------------------------- 1 | # 用PHP在去中心化交易所OceanOne上挂单买卖任意ERC20 token 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/raw/master/php-eth.jpg) 3 | 4 | 在[上一课](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README5.md)中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易!在掌握了ERC20 token之后,就可以把任何token在Ocean上买卖。 5 | 6 | 此处我们用一个叫做Benz的[ERC20 token](https://etherscan.io/token/0xc409b5696c5f9612e194a582e14c8cd41ecdbc67)为例。这个token已经被充值进Mixin Network,你可以在[区块链浏览器](https://mixin.one/snapshots/2b9c216c-ef60-398d-a42a-eba1b298581d )看到这个token在Mixin Network内部的总数和交易 7 | ### 预备知识: 8 | 先将Benz币存入你的钱包,然后使用**getAssets** API读取它的UUID. 9 | 10 | ### 取得该币的UUID 11 | 调用 **getAssets** API 会返回json数据, 如: 12 | 13 | - **asset_id** 币的UUID. 14 | - **public_key** 该币的当前钱包的地址. 15 | - **symbol** 币的名称. 如: Benz. 16 | 17 | ```php 18 | if ($line == 'aw') { 19 | $mixinSdk_eachAccountInstance = GenerateWalletSDKFromCSV(); 20 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAssets(); 21 | foreach ($asset_info as $key => $asset) { 22 | echo $asset["symbol"] . " " . $asset["asset_id"] ." ". $asset["balance"] . 23 | " ". $asset["public_key"].PHP_EOL; 24 | } 25 | } 26 | ``` 27 | 调用 **getAssets** API的完整输出如下: 28 | ```bash 29 | Make your choose:aw 30 | run... 31 | client id is:26b20aa5-40c0-3e00-9de0-666cfb6f2daa 32 | Benz 2b9c216c-ef60-398d-a42a-eba1b298581d 799 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9d 33 | EOS 6cfe566e-4aad-470b-8c9a-2fd35b49c68d 0 34 | CNB 965e5c6e-434c-3fa9-b780-c50f43cd955c 4.72599997 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9d 35 | BTC c6d0c728-2624-429b-8e0d-d9d19b6592fa 0 17z1Rq3VsyvvXvGWiHT8YErjBoFgnhErB8 36 | XIN c94ac88f-4671-3976-b60a-09064f1811e8 0.01 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9d 37 | ``` 38 | ### 限价挂单 39 | - **挂限价买单** 低于或者等于市场价的单. 40 | - **挂限价卖单** 高于或者是等于市场价的单. 41 | 42 | OceanOne支持三种基类价格: USDT, XIN, BTC, 即: Benz/USDT, Benz/XIN, Benz/BTC, 这儿示范Benz/USDT. 43 | 44 | ### 限价挂卖单. 45 | 新币挂单后,需要等一分钟左右,等OceanOne来初始化新币的相关数据. 46 | 47 | ```php 48 | if ( $ocmd == 's1') { 49 | $p = readline("Input the Price of XIN/USDT: "); 50 | $a = readline("Input the Amount of XIN: "); 51 | $tMemo = GenerateOrderMemo("A",USDT_ASSET_ID,$p); 52 | echo $tMemo . PHP_EOL; 53 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 54 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(XIN_ASSET_ID); 55 | print_r($asset_info); 56 | if ( (float) $asset_info["balance"] >= (float) $a ) { 57 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(XIN_ASSET_ID,OCEANONE_BOT, 58 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 59 | $a, 60 | $tMemo); 61 | print_r($transInfos); 62 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 63 | } else { echo "Not enough XIN!\n";} 64 | } 65 | ``` 66 | 67 | ### 限价挂买单. 68 | 新币挂单后,需要等一分钟左右,等OceanOne来初始化新币的相关数据. 69 | 70 | ```php 71 | if ( $ocmd == 'b1') { 72 | $p = readline("Input the Price of XIN/USDT: "); 73 | $a = readline("Input the Amount of USDT: "); 74 | $tMemo = GenerateOrderMemo("B",XIN_ASSET_ID,$p); 75 | echo $tMemo . PHP_EOL; 76 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 77 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(USDT_ASSET_ID); 78 | 79 | print_r($asset_info); 80 | if ( ((float) $asset_info["balance"] >= 1) && ( (float) $asset_info["balance"] >= (float) $a ) ) { 81 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(USDT_ASSET_ID,OCEANONE_BOT, 82 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 83 | $a, 84 | $tMemo); 85 | print_r($transInfos); 86 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 87 | } else { echo "Not enough USDT!\n";} 88 | } 89 | ``` 90 | ### 读取币的价格列表 91 | 读取币的价格列表,来确认挂单是否成功! 92 | 93 | ```php 94 | if ( $ocmd == '2') { getOceanOneMarketInfos(ERC20_BENZ,USDT_ASSET_ID);} 95 | function getOceanOneMarketInfos($targetCoin, $baseCoin) { 96 | $client = new GuzzleHttp\Client(); 97 | $baseUrl = "https://events.ocean.one/markets/".$targetCoin."-".$baseCoin."/book"; 98 | $res = $client->request('GET', $baseUrl, [ 99 | ]); 100 | if ($res->getStatusCode() == "200") { 101 | // echo $res->getStatusCode() . PHP_EOL; 102 | $resInfo = json_decode($res->getBody(), true); 103 | echo "Side | Price | Amount | Funds" . PHP_EOL; 104 | foreach ($resInfo["data"]["data"]["asks"] as $key => $exchange) { 105 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 106 | } 107 | foreach ($resInfo["data"]["data"]["bids"] as $key => $exchange) { 108 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 109 | } 110 | } 111 | } 112 | ``` 113 | ### ERC20相关的操作指令 114 | 115 | Commands list of this source code: 116 | 117 | - trb:Transfer ERC20 from Bot to Wallet 118 | - trm:Transfer ERC20 from Wallet to Master 119 | - o: Ocean.One Exchange 120 | 121 | Make your choose(eg: q for Exit!): 122 | - x: Orders-Book of ERC20/USDT 123 | - x1: Buy ERC20 pay USDT 124 | - x2: Sell ERC20 get USDT 125 | - c: Cancel the order 126 | - q: Exit 127 | 128 | [完整的代码](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/bitcoin_wallet.php) 129 | -------------------------------------------------------------------------------- /README6.md: -------------------------------------------------------------------------------- 1 | # How to list any ERC20 token on decentralized market through PHP 2 | ![](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/php-eth.jpg) 3 | 4 | OceanOne is introduced in [last chapter](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/README5.md), you can trade Bitcoin. All kinds of crypto asset on Mixin Network can be listed on OceanOne.All ERC20 token and EOS token can be listed. Following example will show you how to list a ERC20 token. You can list other token after read the tutorial. 5 | 6 | There is a [ERC20 token](https://etherscan.io/token/0xc409b5696c5f9612e194a582e14c8cd41ecdbc67) called Benz. It is deposited into Mixin Network. You can search all transaction history from [Mixin Network browser](https://mixin.one/snapshots/2b9c216c-ef60-398d-a42a-eba1b298581d ) 7 | 8 | ### Pre-request: 9 | Deposit some coin to your wallet, and then use **getAssets** API fetch the asset UUID which Mixin Network gave it. 10 | 11 | ### Get the ERC-20 compliant coin UUID 12 | The **getAssets** API return json data, for example: 13 | 14 | - **asset_id** UUID of this coin 15 | - **public_key** The wallet address for this coin 16 | - **symbol** Coin name, Eg: Benz. 17 | 18 | ```php 19 | if ($line == 'aw') { 20 | $mixinSdk_eachAccountInstance = GenerateWalletSDKFromCSV(); 21 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAssets(); 22 | foreach ($asset_info as $key => $asset) { 23 | echo $asset["symbol"] . " " . $asset["asset_id"] ." ". $asset["balance"] . 24 | " ". $asset["public_key"].PHP_EOL; 25 | } 26 | } 27 | ``` 28 | The detail information of **getAssets** is output like below: 29 | ```bash 30 | Make your choose:aw 31 | run... 32 | client id is:26b20aa5-40c0-3e00-9de0-666cfb6f2daa 33 | Benz 2b9c216c-ef60-398d-a42a-eba1b298581d 799 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9d 34 | EOS 6cfe566e-4aad-470b-8c9a-2fd35b49c68d 0 35 | CNB 965e5c6e-434c-3fa9-b780-c50f43cd955c 4.72599997 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9d 36 | BTC c6d0c728-2624-429b-8e0d-d9d19b6592fa 0 17z1Rq3VsyvvXvGWiHT8YErjBoFgnhErB8 37 | XIN c94ac88f-4671-3976-b60a-09064f1811e8 0.01 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9d 38 | ``` 39 | ### Make the limit order 40 | - **Limit Order to Buy** at or below the market. 41 | - **Limit Order to Sell** at or above the market. 42 | 43 | OceanOne support three base coin: USDT, XIN, BTC, that mean you can sell or buy it between USDT, XIN, BTC, so, you have there order: Benz/USDT, Benz/XIN, Benz/BTC, here show you how to make the sell order with USDT. 44 | 45 | ### Make the limit order to sell. 46 | 47 | ```php 48 | if ( $ocmd == 's1') { 49 | $p = readline("Input the Price of XIN/USDT: "); 50 | $a = readline("Input the Amount of XIN: "); 51 | $tMemo = GenerateOrderMemo("A",USDT_ASSET_ID,$p); 52 | echo $tMemo . PHP_EOL; 53 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 54 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(XIN_ASSET_ID); 55 | print_r($asset_info); 56 | if ( (float) $asset_info["balance"] >= (float) $a ) { 57 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(XIN_ASSET_ID,OCEANONE_BOT, 58 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 59 | $a, 60 | $tMemo); 61 | print_r($transInfos); 62 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 63 | } else { echo "Not enough XIN!\n";} 64 | } 65 | ``` 66 | 67 | ### Make the limit order to buy. 68 | After the order commit, wait 1 minute to let the OceanOne exchange initialize it. 69 | ```php 70 | if ( $ocmd == 'b1') { 71 | $p = readline("Input the Price of XIN/USDT: "); 72 | $a = readline("Input the Amount of USDT: "); 73 | $tMemo = GenerateOrderMemo("B",XIN_ASSET_ID,$p); 74 | echo $tMemo . PHP_EOL; 75 | $mixinSdk_WalletInstance = GenerateWalletSDKFromCSV(); 76 | $asset_info = $mixinSdk_WalletInstance->Wallet()->readAsset(USDT_ASSET_ID); 77 | 78 | print_r($asset_info); 79 | if ( ((float) $asset_info["balance"] >= 1) && ( (float) $asset_info["balance"] >= (float) $a ) ) { 80 | $transInfos = $mixinSdk_WalletInstance->Wallet()->transfer(USDT_ASSET_ID,OCEANONE_BOT, 81 | $mixinSdk_WalletInstance->getConfig()['default']['pin'], 82 | $a, 83 | $tMemo); 84 | print_r($transInfos); 85 | echo "The Order ID (trace_id) is: " . $transInfos["trace_id"] . PHP_EOL; 86 | } else { echo "Not enough USDT!\n";} 87 | } 88 | ``` 89 | ### Read orders book from Ocean.one 90 | Now, check the orders-book. 91 | 92 | ```php 93 | if ( $ocmd == '2') { getOceanOneMarketInfos(ERC20_BENZ,USDT_ASSET_ID);} 94 | function getOceanOneMarketInfos($targetCoin, $baseCoin) { 95 | $client = new GuzzleHttp\Client(); 96 | $baseUrl = "https://events.ocean.one/markets/".$targetCoin."-".$baseCoin."/book"; 97 | $res = $client->request('GET', $baseUrl, [ 98 | ]); 99 | if ($res->getStatusCode() == "200") { 100 | // echo $res->getStatusCode() . PHP_EOL; 101 | $resInfo = json_decode($res->getBody(), true); 102 | echo "Side | Price | Amount | Funds" . PHP_EOL; 103 | foreach ($resInfo["data"]["data"]["asks"] as $key => $exchange) { 104 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 105 | } 106 | foreach ($resInfo["data"]["data"]["bids"] as $key => $exchange) { 107 | echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; 108 | } 109 | } 110 | } 111 | ``` 112 | ### Command of make orders 113 | 114 | Commands list of this source code: 115 | 116 | - trb:Transfer ERC20 from Bot to Wallet 117 | - trm:Transfer ERC20 from Wallet to Master 118 | - o: Ocean.One Exchange 119 | 120 | Make your choose(eg: q for Exit!): 121 | - x: Orders-Book of ERC20/USDT 122 | - x1: Buy ERC20 pay USDT 123 | - x2: Sell ERC20 get USDT 124 | - c: Cancel the order 125 | - q: Exit 126 | 127 | [Full source code](https://github.com/wenewzhang/mixin_labs-php-bot/blob/master/bitcoin_wallet.php) 128 | -------------------------------------------------------------------------------- /app.php: -------------------------------------------------------------------------------- 1 | 15 12 | ]); 13 | class callTraitClass { 14 | use MixinSDKTrait; 15 | public $config; 16 | public function __construct() 17 | { 18 | $config = require(__DIR__.'/config.php'); 19 | $this->config = $config; 20 | } 21 | } 22 | $callTrait = new callTraitClass(); 23 | $Token = $callTrait->getToken('GET', '/', ''); 24 | print_r($callTrait->config['client_id']); 25 | // $Header = 'Authorization'.'Bearer '.$Token; 26 | // print($Header); 27 | $connector = new \Ratchet\Client\Connector($loop,$reactConnector); 28 | // $connector('ws://127.0.0.1:9000', ['protocol' => 'Mixin-Blaze-1'], ['Origin' => 'http://localhost', 29 | $connector('wss://blaze.mixin.one', ['protocol' => 'Mixin-Blaze-1'],[ 30 | 'Authorization' => 'Bearer '.$Token 31 | ]) 32 | ->then(function(Ratchet\Client\WebSocket $conn) { 33 | $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) { 34 | $jsMsg = json_decode(gzdecode($msg)); 35 | print_r($jsMsg); 36 | if ($jsMsg->action === 'CREATE_MESSAGE' and property_exists($jsMsg,'data')) { 37 | echo "\nNeed reply server a receipt!\n"; 38 | $RspMsg = generateReceipt($jsMsg->data->message_id); 39 | $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY); 40 | $conn->send($msg); 41 | 42 | if ($jsMsg->data->category === 'PLAIN_TEXT') { 43 | echo "PLAIN_TEXT:".base64_decode($jsMsg->data->data); 44 | $isCmd = strtolower(base64_decode($jsMsg->data->data)); 45 | if ($isCmd ==='?' or $isCmd ==='help') { 46 | $msgData = sendUsage($jsMsg->data->conversation_id); 47 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 48 | $conn->send($msg); 49 | } elseif ($isCmd === '1') { 50 | // print($callTrait->config['client_id']); 51 | $msgData = sendAppButtons($jsMsg); 52 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 53 | $conn->send($msg); 54 | }//end of pay1 55 | 56 | elseif ($isCmd === '2') { 57 | // print($callTrait->config['client_id']); 58 | $msgData = sendAppCard($jsMsg); 59 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 60 | $conn->send($msg); 61 | }//end of pay2 62 | elseif ($isCmd === '3') { 63 | transfer(); 64 | } else { 65 | $msgData = sendPlainText($jsMsg->data->conversation_id, 66 | base64_decode($jsMsg->data->data)); 67 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 68 | $conn->send($msg); 69 | } 70 | } //end of PLAIN_TEXT 71 | if ($jsMsg->data->category === 'SYSTEM_ACCOUNT_SNAPSHOT') { 72 | // refundInstant 73 | echo "user id:".$jsMsg->data->user_id; 74 | $dtPay = json_decode(base64_decode($jsMsg->data->data)); 75 | print_r($dtPay); 76 | if ($dtPay->amount > 0) { 77 | echo "paid!".$dtPay->asset_id; 78 | refundInstant($dtPay->asset_id,$dtPay->amount,$jsMsg->data->user_id); 79 | } 80 | } //end of SYSTEM_ACCOUNT_SNAPSHOT 81 | } //end of CREATE_MESSAGE 82 | 83 | }); 84 | 85 | $conn->on('close', function($code = null, $reason = null) { 86 | echo "Connection closed ({$code} - {$reason})\n"; 87 | }); 88 | /* start listen for the incoming message */ 89 | $message = [ 90 | 'id' => Uuid::uuid4()->toString(), 91 | 'action' => 'LIST_PENDING_MESSAGES', 92 | ]; 93 | print_r(json_encode($message)); 94 | $msg = new Frame(gzencode(json_encode($message)),true,Frame::OP_BINARY); 95 | $conn->send($msg); 96 | // $conn->send(gzencode($msg,1,FORCE_DEFLATE)); 97 | }, function(\Exception $e) use ($loop) { 98 | echo "Could not connect: {$e->getMessage()}\n"; 99 | $loop->stop(); 100 | }); 101 | 102 | $loop->run(); 103 | 104 | 105 | function sendUsage($conversation_id):Array { 106 | $msgHelp = << $conversation_id, 119 | 'category' => 'PLAIN_TEXT', 120 | 'status' => 'SENT', 121 | 'message_id' => Uuid::uuid4()->toString(), 122 | 'data' => base64_encode($msgContent),//base64_encode("hello!"), 123 | ]; 124 | $msgPayButton = [ 125 | 'id' => Uuid::uuid4()->toString(), 126 | 'action' => 'CREATE_MESSAGE', 127 | 'params' => $msgParams, 128 | ]; 129 | return $msgPayButton; 130 | } 131 | function sendAppButtons($jsMsg):Array { 132 | $client_id = (require "./config.php")['client_id']; 133 | $payLinkEOS = "https://mixin.one/pay?recipient=". 134 | $client_id."&asset=". 135 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 136 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 137 | "&memo="; 138 | $payLinkBTC = "https://mixin.one/pay?recipient=". 139 | $client_id."&asset=". 140 | "c6d0c728-2624-429b-8e0d-d9d19b6592fa". 141 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 142 | "&memo="; 143 | $msgData = [[ 144 | 'label' => "Pay 0.001 EOS", 145 | 'color' => "#FFABAB", 146 | 'action' => $payLinkEOS, 147 | ],[ 148 | 'label' => "Pay 0.0001 BTC", 149 | 'color' => "#00EEFF", 150 | 'action' => $payLinkBTC, 151 | ], 152 | ]; 153 | $msgParams = [ 154 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 155 | // 'recipient_id' => $jsMsg->data->user_id, 156 | 'category' => 'APP_BUTTON_GROUP',//'PLAIN_TEXT', 157 | 'status' => 'SENT', 158 | 'message_id' => Uuid::uuid4()->toString(), 159 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 160 | ]; 161 | $msgPayButtons = [ 162 | 'id' => Uuid::uuid4()->toString(), 163 | 'action' => 'CREATE_MESSAGE', 164 | 'params' => $msgParams, 165 | ]; 166 | return $msgPayButtons; 167 | } 168 | 169 | function sendAppCard($jsMsg):Array 170 | { 171 | $client_id = (require "./config.php")['client_id']; 172 | $payLink = "https://mixin.one/pay?recipient=". 173 | $client_id."&asset=". 174 | "6cfe566e-4aad-470b-8c9a-2fd35b49c68d". 175 | "&amount=0.0001"."&trace=".Uuid::uuid4()->toString(). 176 | "&memo="; 177 | $msgData = [ 178 | 'icon_url' => "https://mixin.one/assets/98b586edb270556d1972112bd7985e9e.png", 179 | 'title' => "Pay 0.001 EOS", 180 | 'description' => "pay", 181 | 'action' => $payLink, 182 | ]; 183 | $msgParams = [ 184 | 'conversation_id' => $jsMsg->data->conversation_id,// $callTrait->config[client_id], 185 | // 'recipient_id' => $jsMsg->data->user_id, 186 | 'category' => 'APP_CARD',//'PLAIN_TEXT', 187 | 'status' => 'SENT', 188 | 'message_id' => Uuid::uuid4()->toString(), 189 | 'data' => base64_encode(json_encode($msgData)),//base64_encode("hello!"), 190 | ]; 191 | $msgPayButton = [ 192 | 'id' => Uuid::uuid4()->toString(), 193 | 'action' => 'CREATE_MESSAGE', 194 | 'params' => $msgParams, 195 | ]; 196 | return $msgPayButton; 197 | } 198 | 199 | function transfer() { 200 | $mixinSdk = new MixinSDK(require './config.php'); 201 | print_r($mixinSdk->getConfig()); 202 | } 203 | 204 | function generateReceipt($msgID):Array { 205 | $IncomingMsg = ["message_id" => $msgID, "status" => "READ"]; 206 | $RspMsg = ["id" => Uuid::uuid4()->toString(), "action" => "ACKNOWLEDGE_MESSAGE_RECEIPT", 207 | "params" => $IncomingMsg]; 208 | return $RspMsg; 209 | } 210 | 211 | function refundInstant($_assetID,$_amount,$_opponent_id) { 212 | $mixinSdk = new MixinSDK(require './config.php'); 213 | // print_r(); 214 | $BotInfo = $mixinSdk->Wallet()->transfer($_assetID,$_opponent_id, 215 | $mixinSdk->getConfig()['default']['pin'],$_amount); 216 | print_r($BotInfo); 217 | } 218 | -------------------------------------------------------------------------------- /bitcoin-transfer-to-bot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/bitcoin-transfer-to-bot.jpg -------------------------------------------------------------------------------- /call_apis.php: -------------------------------------------------------------------------------- 1 | config = $config; 16 | } 17 | } 18 | 19 | $mixinSdk_BotInstance = new MixinSDK(require './config.php'); 20 | 21 | const PIN = "945689"; 22 | const MASTER_ID = "37222956"; 23 | const EXIN_BOT = "61103d28-3ac2-44a2-ae34-bd956070dab1"; 24 | const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; 25 | const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; 26 | const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; 27 | const BTC_WALLET_ADDR = "14T129GTbXXPGXXvZzVaNLRFPeHXD1C25C"; 28 | const AMOUNT = "0.1"; 29 | const EOS_THIRD_EXCHANGE_NAME 30 | = "huobideposit"; 31 | const EOS_THIRD_EXCHANGE_TAG 32 | = "1872050"; 33 | // Mixin Network support cryptocurrencies (2019-02-19) 34 | // |EOS|6cfe566e-4aad-470b-8c9a-2fd35b49c68d 35 | // |CNB|965e5c6e-434c-3fa9-b780-c50f43cd955c 36 | // |BTC|c6d0c728-2624-429b-8e0d-d9d19b6592fa 37 | // |ETC|2204c1ee-0ea2-4add-bb9a-b3719cfff93a 38 | // |XRP|23dfb5a5-5d7b-48b6-905f-3970e3176e27 39 | // |XEM|27921032-f73e-434e-955f-43d55672ee31 40 | // |ETH|43d61dcd-e413-450d-80b8-101d5e903357 41 | // |DASH|6472e7e3-75fd-48b6-b1dc-28d294ee1476 42 | // |DOGE|6770a1e5-6086-44d5-b60f-545f9d9e8ffd 43 | // |LTC|76c802a2-7c88-447f-a93e-c29c9e5dd9c8 44 | // |SC|990c4c29-57e9-48f6-9819-7d986ea44985 45 | // |ZEN|a2c5d22b-62a2-4c13-b3f0-013290dbac60 46 | // |ZEC|c996abc9-d94e-4494-b1cf-2a3fd3ac5714 47 | // |BCH|fd11b6e3-0b87-41f1-a41f-f0e9b49e5bf0 48 | 49 | $msg = "1: Create user and update PIN\n2: Read Bitcoin balance & address \n3: Read USDT balance & address\n4: Read EOS balance\n"; 50 | $msg .= "5: Read EOS address\n6: Transfer Bitcoin from bot to new user\n7: Transfer Bitcoin from new user to Master\n7e: Transfer EOS from new user to bot\n"; 51 | $msg .= "8: Withdraw bot's Bitcoin\n9: Withdraw bot's EOS\nqu: Read market price(USDT)\nqb: Read market price(BTC)\nb: Balance of bot (USDT & BTC & EOS)\n"; 52 | $msg .= "s: Read Snapshots \ntb: Transfer 0.0001 BTC buy USDT\ntu: Transfer $1 USDT buy BTC\n"; 53 | $msg .= "q: Exit \nMake your choose:"; 54 | while (true) { 55 | echo $msg; 56 | $line = readline(""); 57 | if ($line != 'q') print("run...\n"); 58 | if ($line == '1') { 59 | $tomcat_info = $mixinSdk_BotInstance->Network()->createUser("Tom cat"); 60 | print_r($tomcat_info); 61 | print($tomcat_info["pubKey"]); 62 | 63 | $tomcat_Config = array(); 64 | $tomcat_Config["private_key"] = $tomcat_info["priKey"]; 65 | $tomcat_Config["pin_token"] = $tomcat_info["pin_token"]; 66 | $tomcat_Config["session_id"] = $tomcat_info["session_id"]; 67 | $tomcat_Config["client_id"] = $tomcat_info["user_id"]; 68 | $tomcat_Config["pin"] = PIN; 69 | $mixinSdk_tomcat = new MixinSDK($tomcat_Config); 70 | 71 | $pinInfo = $mixinSdk_tomcat->Pin()->updatePin('',PIN); 72 | print_r($pinInfo); 73 | $csvary = array($tomcat_Config); 74 | $fp = fopen('new_users.csv', 'a'); 75 | foreach ($csvary as $fields) { 76 | fputcsv($fp, $fields); 77 | } 78 | fclose($fp); 79 | } 80 | if ($line == 'b') { 81 | $asset_info = $mixinSdk_BotInstance->Wallet()->readAsset(BTC_ASSET_ID); 82 | print_r("Bot Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 83 | $asset_info = $mixinSdk_BotInstance->Wallet()->readAsset(USDT_ASSET_ID); 84 | print_r("Bot USDT wallet balance is :".$asset_info["balance"]."\n"); 85 | $asset_info = $mixinSdk_BotInstance->Wallet()->readAsset(EOS_ASSET_ID); 86 | print_r("Bot EOS wallet balance is :".$asset_info["balance"]."\n"); 87 | } 88 | if ($line == '2') { 89 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 90 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 91 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 92 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 93 | print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); 94 | print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n"); 95 | } 96 | fclose($handle); 97 | } else print("Create user first\n"); 98 | } 99 | if ($line == '3') { 100 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 101 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 102 | $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); 103 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(USDT_ASSET_ID); 104 | print_r("USDT wallet address is :".$asset_info["public_key"]."\n"); 105 | print_r("USDT wallet balance is :".$asset_info["balance"]."\n"); 106 | } 107 | fclose($handle); 108 | } else print("Create user first\n"); 109 | } 110 | if ($line == '4') { 111 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 112 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 113 | $mixinSdk_eachAccountInstance= new MixinSDK(GenerateConfigByCSV($data)); 114 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(EOS_ASSET_ID); 115 | print_r("EOS wallet balance is :".$asset_info["balance"]."\n"); 116 | } 117 | fclose($handle); 118 | } else print("Create user first\n"); 119 | } 120 | if ($line == '5') { 121 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 122 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 123 | $mixinSdk_eachAccountInstance= new MixinSDK(GenerateConfigByCSV($data)); 124 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(EOS_ASSET_ID); 125 | print_r($asset_info); 126 | print_r("EOS wallet address is :".$asset_info["account_name"]."\n"); 127 | print_r($asset_info["account_tag"]."\n"); 128 | } 129 | fclose($handle); 130 | } else print("Create user first\n"); 131 | 132 | } 133 | if ($line == '6') { 134 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 135 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 136 | $new_user_id = $data[3]; 137 | $trans_info = $mixinSdk_BotInstance->Wallet()->transfer(EOS_ASSET_ID,$new_user_id, 138 | $mixinSdk_BotInstance->getConfig()['default']['pin'],AMOUNT); 139 | print_r($trans_info); 140 | } 141 | fclose($handle); 142 | } else print("Create user first\n"); 143 | } 144 | if ($line == '7') { 145 | $userInfo = $mixinSdk_BotInstance->Network()->readUser(MASTER_ID); 146 | if (isset($userInfo["user_id"])) { 147 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 148 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 149 | $mixinSdk_eachAccountInstance= new MixinSDK(GenerateConfigByCSV($data)); 150 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); 151 | if ( (float) $asset_info["balance"] > 0 ) { 152 | $trans_info = $mixinSdk_eachAccountInstance->Wallet()->transfer(BTC_ASSET_ID,$userInfo["user_id"], 153 | $mixinSdk_eachAccountInstance->getConfig()['default']['pin'],$asset_info["balance"]); 154 | print_r($trans_info); 155 | } else print($data[3] . " has no coins!\n"); 156 | } 157 | fclose($handle); 158 | } else print("Create user first\n"); 159 | } else print("Can not find this user id by Mixin ID!"); 160 | } 161 | if ($line == '7e') { 162 | // $userInfo = $mixinSdk_BotInstance->Network()->readUser(MASTER_ID); 163 | if (($handle = fopen("new_users.csv", "r")) !== FALSE) { 164 | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 165 | $mixinSdk_eachAccountInstance= new MixinSDK(GenerateConfigByCSV($data)); 166 | $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(EOS_ASSET_ID); 167 | if ( (float) $asset_info["balance"] > 0 ) { 168 | $trans_info = $mixinSdk_eachAccountInstance->Wallet()->transfer(EOS_ASSET_ID, 169 | $mixinSdk_BotInstance->getConfig()['default']['client_id'], 170 | $mixinSdk_eachAccountInstance->getConfig()['default']['pin'], 171 | $asset_info["balance"]); 172 | print_r($trans_info); 173 | } else print($data[3] . " has no coins!\n"); 174 | } 175 | fclose($handle); 176 | } else print("Create user first\n"); 177 | } 178 | if ($line == '8') { 179 | $btcInfo = $mixinSdk_BotInstance->Wallet()->createAddress(BTC_ASSET_ID, 180 | BTC_WALLET_ADDR, 181 | $mixinSdk_BotInstance->getConfig()['default']['pin'], 182 | "BTC withdral",false); 183 | print("Bitcoin winthdrawal fee is:".$btcInfo["fee"]."\n"); 184 | $asset_info = $mixinSdk_BotInstance->Wallet()->readAsset(BTC_ASSET_ID); 185 | $wdAmount = (float) $asset_info["balance"] - (float) $wdInfo["fee"]; 186 | echo "EOS withdraw amount is: " . $wdAmount . PHP_EOL; 187 | if ( $wdAmount > 0 ) { 188 | echo "Are you deposit Bitcoin " . floatval($wdAmount). " to " . BTC_WALLET_ADDR . "(y/n)"; 189 | $cmd = readline(""); 190 | if ($cmd == 'y' ) { 191 | $wdInfo = $mixinSdk_BotInstance->Wallet()->withdrawal($btcInfo["address_id"], 192 | floatval($wdAmount), 193 | $mixinSdk_BotInstance->getConfig()['default']['pin'], 194 | "btc withdraw"); 195 | print_r($wdInfo); 196 | } 197 | } else echo "Not Enough asset to withdraw!" . PHP_EOL; 198 | } 199 | if ($line == '9') { 200 | $wdInfo = $mixinSdk_BotInstance->Wallet()->createAddress(EOS_ASSET_ID, 201 | EOS_THIRD_EXCHANGE_TAG, 202 | $mixinSdk_BotInstance->getConfig()['default']['pin'], 203 | EOS_THIRD_EXCHANGE_NAME,true); 204 | print("EOS winthdrawal fee is:".$wdInfo["fee"]."\n"); 205 | $asset_info = $mixinSdk_BotInstance->Wallet()->readAsset(EOS_ASSET_ID); 206 | $wdAmount = (float) $asset_info["balance"] - (float) $wdInfo["fee"]; 207 | echo "EOS withdraw amount is: " . $wdAmount . PHP_EOL; 208 | if ( $wdAmount > 0 ) { 209 | echo "Are you deposit EOS " . floatval($wdAmount). " to " . EOS_THIRD_EXCHANGE_NAME . " " . EOS_THIRD_EXCHANGE_TAG . "(y/n)"; 210 | $cmd = readline(""); 211 | if ($cmd == 'y' ) { 212 | $wdInfo = $mixinSdk_BotInstance->Wallet()->withdrawal($wdInfo["address_id"], 213 | floatval($wdAmount), 214 | $mixinSdk_BotInstance->getConfig()['default']['pin'], 215 | "eos withdraw"); 216 | print_r($wdInfo); 217 | } 218 | } else echo "Not Enough asset to withdraw!" . PHP_EOL; 219 | } 220 | if ($line == 's') { 221 | $limit = 20; 222 | $offset = '2019-03-10T01:58:25.362528Z'; 223 | $snapInfo = $mixinSdk_BotInstance->Wallet()->readUserSnapshots($limit, $offset); 224 | // print_r($networkInfo2); 225 | foreach ($snapInfo as $record) { 226 | // echo $key . PHP_EOL; 227 | // print_r($record); 228 | if ($record['amount'] > 0 and $record['memo'] != '') { 229 | echo "------------MEMO:-coin--exchange--------------" . PHP_EOL; 230 | echo "memo: " . $record['memo'] . PHP_EOL; 231 | // print_r($dtPay->memo); 232 | echo "You Get Coins: ". $record['asset_id']. " " . $record['amount'] . PHP_EOL; 233 | $memoUnpack = MessagePack::unpack(base64_decode($record['memo'])); 234 | $feeAssetID = Uuid::fromBytes($memoUnpack['FA'])->toString(); 235 | $OrderID = Uuid::fromBytes($memoUnpack['O'])->toString(); 236 | if ($memoUnpack['C'] == 1000) { 237 | echo "Successful Exchange:". PHP_EOL; 238 | echo "Fee asset ID: " . $feeAssetID . " fee is :" . $memoUnpack['F'] . PHP_EOL; 239 | echo "Order ID: " . $OrderID . " Price is :" . $memoUnpack['P'] . PHP_EOL; 240 | } else print_r($memoUnpack); 241 | echo "--------------memo-record end---------------" . PHP_EOL; 242 | } 243 | } 244 | } 245 | if ($line == 'qu') { 246 | $marketInfo = getExchangeCoins(USDT_ASSET_ID); 247 | // echo $marketInfo; 248 | } 249 | if ($line == 'tb') { 250 | $memo = base64_encode(MessagePack::pack([ 251 | 'A' => Uuid::fromString(USDT_ASSET_ID)->getBytes(), 252 | ])); 253 | echo PHP_EOL . $memo . PHP_EOL; 254 | // $mixinSdk_eachAccountInstance= new MixinSDK(GenerateConfigByCSV($data)); 255 | $handle = fopen("new_users.csv", "r"); 256 | $data = fgetcsv($handle, 1, ","); 257 | $mixinSdk_eachAccountInstance= new MixinSDK(GenerateConfigByCSV($data)); 258 | $transInfo = $mixinSdk_eachAccountInstance->Wallet()->transfer(BTC_ASSET_ID,EXIN_BOT,PIN,AMOUNT,$memo); 259 | fclose($handle); 260 | } 261 | if ($line == 'tu') { 262 | $memo = base64_encode(MessagePack::pack([ 263 | 'A' => Uuid::fromString(BTC_ASSET_ID)->getBytes(), 264 | ])); 265 | echo PHP_EOL . $memo . PHP_EOL; 266 | // $mixinSdk_eachAccountInstance= new MixinSDK(GenerateConfigByCSV($data)); 267 | $handle = fopen("new_users.csv", "r"); 268 | $data = fgetcsv($handle, 1, ","); 269 | $mixinSdk_eachAccountInstance= new MixinSDK(GenerateConfigByCSV($data)); 270 | $transInfo = $mixinSdk_eachAccountInstance->Wallet()->transfer(USDT_ASSET_ID,EXIN_BOT,PIN,"1",$memo); 271 | fclose($handle); 272 | } 273 | if ($line == 'qb') { 274 | $marketInfo = getExchangeCoins(BTC_ASSET_ID); 275 | // echo $marketInfo; 276 | } 277 | if ($line == 'q') { 278 | exit(); 279 | } 280 | } 281 | 282 | function GenerateConfigByCSV($data) :array { 283 | print("client id is:".$data[3]."\n"); 284 | $newConfig = array(); 285 | $newConfig["private_key"] = $data[0]; 286 | $newConfig["pin_token"] = $data[1]; 287 | $newConfig["session_id"] = $data[2]; 288 | $newConfig["client_id"] = $data[3]; 289 | $newConfig["pin"] = $data[4]; 290 | return $newConfig; 291 | } 292 | 293 | function getExchangeCoins($base_coin) :string { 294 | $client = new GuzzleHttp\Client(); 295 | $res = $client->request('GET', 'https://exinone.com/exincore/markets?base_asset='.$base_coin, [ 296 | ]); 297 | $result = ""; 298 | if ($res->getStatusCode() == "200") { 299 | // echo $res->getStatusCode() . PHP_EOL; 300 | $resInfo = json_decode($res->getBody(), true); 301 | echo "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 302 | $result = "Asset ID | Asset Symbol | Price | Amount | Exchanges" . PHP_EOL; 303 | foreach ($resInfo["data"] as $key => $coinInfo) { 304 | echo ($coinInfo["exchange_asset"] ." ".$coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 305 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "); 306 | $result .= $coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 307 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "; 308 | foreach ($coinInfo["exchanges"] as $key => $exchange) { 309 | echo $exchange . " "; 310 | $result .= $exchange . " "; 311 | } 312 | echo PHP_EOL; 313 | $result .= PHP_EOL; 314 | } 315 | } 316 | return $result; 317 | } 318 | -------------------------------------------------------------------------------- /click-link-to-pay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/click-link-to-pay.jpg -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wenewzhang/mixin_labs-php-bot", 3 | "description": "php 7 bot for mixin network", 4 | "type": "project", 5 | "require": { 6 | "exinone/mixin-sdk-php": "^1.1", 7 | "wrench/wrench": "^2.0", 8 | "ratchet/pawl": "^0.3.3", 9 | "cboden/ratchet": "^0.4.1", 10 | "ramsey/uuid": "^3.8", 11 | "rybakit/msgpack": "^0.5.4" 12 | }, 13 | "license": "BSD", 14 | "authors": [ 15 | { 16 | "name": "wenewzhang", 17 | "email": "wenewboy@gmail.com" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /config-example.php: -------------------------------------------------------------------------------- 1 | '7000101716', 4 | 'client_id' => 'a1ce2967-a534-417d-bf12-c86571e4eefa', 5 | 'client_secret' => 'f8e0241bc76461a6032a7a80f9c8b9b10303308cbf772b218bbad2a819c62556', 6 | 'pin' => '806669', 7 | 'pin_token' => 'H8U9BJly4EjN5d/LPUjjXbgHOJDzqyHHa/Os9hT6g5P06Xl475XlsL7KB0Lj15jpBL3SLlgDEiz3+drchsX8fPfEeido8hgnmZJJRkAW+S2p5AdTShWQmpi03fdbkK4ARqOpBIRXu9l8RJl17I4N4ZNsx09O2p2EfbQDDjaVDVg=', 8 | 'session_id' => 'fe4ff62a-ce5a-4db3-9f53-3f365a260541', 9 | 'private_key' => << 15 12 | ]); 13 | $connector = new \Ratchet\Client\Connector($loop,$reactConnector); 14 | class callTraitClass { 15 | use MixinSDKTrait; 16 | public $config; 17 | public function __construct() 18 | { 19 | $config = require(__DIR__.'/config.php'); 20 | $this->config = $config; 21 | } 22 | } 23 | $callTrait = new callTraitClass(); 24 | $Token = $callTrait->getToken('GET', '/', ''); 25 | // $connector('ws://127.0.0.1:9000', ['protocol' => 'Mixin-Blaze-1'], ['Origin' => 'http://localhost', 26 | $connector('wss://blaze.mixin.one', ['protocol' => 'Mixin-Blaze-1'],[ 27 | 'Authorization' => 'Bearer '.$Token 28 | ]) 29 | ->then(function(Ratchet\Client\WebSocket $conn) { 30 | $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) { 31 | $jsMsg = json_decode(gzdecode($msg)); 32 | print_r($jsMsg); 33 | if ($jsMsg->action === 'CREATE_MESSAGE' and property_exists($jsMsg,'data')) { 34 | echo "\nNeed reply server a receipt!\n"; 35 | $RspMsg = generateReceipt($jsMsg->data->message_id); 36 | $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY); 37 | $conn->send($msg); 38 | 39 | if ($jsMsg->data->category === 'PLAIN_TEXT') { 40 | $msgData = sendPlainText($jsMsg->data->conversation_id, 41 | base64_decode($jsMsg->data->data)); 42 | $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY); 43 | $conn->send($msg); 44 | } //end of PLAIN_TEXT 45 | } //end of CREATE_MESSAGE 46 | 47 | }); 48 | $conn->on('close', function($code = null, $reason = null) { 49 | echo "Connection closed ({$code} - {$reason})\n"; 50 | }); 51 | /* start listen for the incoming message */ 52 | $message = [ 53 | 'id' => Uuid::uuid4()->toString(), 54 | 'action' => 'LIST_PENDING_MESSAGES', 55 | ]; 56 | print_r(json_encode($message)); 57 | $msg = new Frame(gzencode(json_encode($message)),true,Frame::OP_BINARY); 58 | $conn->send($msg); 59 | // $conn->send(gzencode($msg,1,FORCE_DEFLATE)); 60 | }, function(\Exception $e) use ($loop) { 61 | echo "Could not connect: {$e->getMessage()}\n"; 62 | $loop->stop(); 63 | }); 64 | 65 | $loop->run(); 66 | 67 | 68 | function sendPlainText($conversation_id,$msgContent):Array { 69 | 70 | $msgParams = [ 71 | 'conversation_id' => $conversation_id, 72 | 'category' => 'PLAIN_TEXT', 73 | 'status' => 'SENT', 74 | 'message_id' => Uuid::uuid4()->toString(), 75 | 'data' => base64_encode($msgContent),//base64_encode("hello!"), 76 | ]; 77 | $msgPayButton = [ 78 | 'id' => Uuid::uuid4()->toString(), 79 | 'action' => 'CREATE_MESSAGE', 80 | 'params' => $msgParams, 81 | ]; 82 | return $msgPayButton; 83 | } 84 | 85 | function generateReceipt($msgID):Array { 86 | $IncomingMsg = ["message_id" => $msgID, "status" => "READ"]; 87 | $RspMsg = ["id" => Uuid::uuid4()->toString(), "action" => "ACKNOWLEDGE_MESSAGE_RECEIPT", 88 | "params" => $IncomingMsg]; 89 | return $RspMsg; 90 | } 91 | -------------------------------------------------------------------------------- /mixin_network-keys.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/mixin_network-keys.jpg -------------------------------------------------------------------------------- /newuser-transfer-bitcoin-to-me.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/newuser-transfer-bitcoin-to-me.jpg -------------------------------------------------------------------------------- /others/TEST_README.md: -------------------------------------------------------------------------------- 1 | composer require phpunit/phpunit 2 | 3 | vendor/exinone/mixin-sdk-php/tests/Feature 4 | ../../../../bin/phpunit WalletApiTest.php 5 | -------------------------------------------------------------------------------- /others/chat-client.php: -------------------------------------------------------------------------------- 1 | then(function($conn) { 6 | // \Ratchet\Client\connect('ws://localhost:8080/echo')->then(function($conn) { 7 | \Ratchet\Client\connect('ws://localhost:8080')->then(function($conn) { 8 | $conn->on('message', function($msg) use ($conn) { 9 | echo "Received: {$msg}\n"; 10 | $conn->close(); 11 | }); 12 | 13 | $conn->send('Hello World!'); 14 | }, function ($e) { 15 | echo "Could not connect: {$e->getMessage()}\n"; 16 | }); 17 | -------------------------------------------------------------------------------- /others/chat.php: -------------------------------------------------------------------------------- 1 | clients = new \SplObjectStorage; 17 | } 18 | 19 | public function onOpen(ConnectionInterface $conn) { 20 | $this->clients->attach($conn); 21 | } 22 | 23 | public function onMessage(ConnectionInterface $from, $msg) { 24 | foreach ($this->clients as $client) { 25 | if ($from != $client) { 26 | $client->send($msg); 27 | } 28 | } 29 | } 30 | 31 | public function onClose(ConnectionInterface $conn) { 32 | $this->clients->detach($conn); 33 | } 34 | 35 | public function onError(ConnectionInterface $conn, \Exception $e) { 36 | $conn->close(); 37 | } 38 | } 39 | 40 | // Run the server application through the WebSocket protocol on port 8080 41 | $app = new Ratchet\App('localhost', 8080); 42 | $app->route('/chat', new MyChat, array('*')); 43 | $app->route('/echo', new Ratchet\Server\EchoServer, array('*')); 44 | $app->run(); 45 | -------------------------------------------------------------------------------- /others/coin_exchange.php: -------------------------------------------------------------------------------- 1 | Uuid::fromString('c6d0c728-2624-429b-8e0d-d9d19b6592fa')->getBytes(), 11 | ])); 12 | // gaFBxBDG0McoJiRCm44N2dGbZZL6 13 | 14 | // Parse memo 15 | $uuid = Uuid::fromBytes( 16 | MessagePack::unpack(base64_decode($memo))['A'] 17 | )->toString(); 18 | // getExchangeCoins("815b0b1a-2764-3736-8faa-42d694fa620a"); 19 | // getExchangeCoins("c6d0c728-2624-429b-8e0d-d9d19b6592fa"); 20 | getExchangeCoins(); 21 | 22 | function getExchangeCoins($base_coin = "") :string { 23 | $client = new GuzzleHttp\Client(); 24 | if ($base_coin === "") $url = 'https://exinone.com/exincore/markets'; 25 | else $url = 'https://exinone.com/exincore/markets?base_asset='.$base_coin; 26 | $res = $client->request('GET', $url, [ 27 | ]); 28 | $result = ""; 29 | if ($res->getStatusCode() == "200") { 30 | // echo $res->getStatusCode() . PHP_EOL; 31 | $resInfo = json_decode($res->getBody(), true); 32 | echo "------Asset ID | Asset Symbol | Price | Amount | Exchanges --------" . PHP_EOL; 33 | $result = "------Asset ID | Asset Symbol | Price | Amount | Exchanges --------" . PHP_EOL; 34 | foreach ($resInfo["data"] as $key => $coinInfo) { 35 | echo ($coinInfo["exchange_asset"] ." ".$coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 36 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "); 37 | $result .= $coinInfo["exchange_asset"] ." ".$coinInfo["exchange_asset_symbol"]. "/". $coinInfo["base_asset_symbol"] . 38 | " ". $coinInfo["price"] ." ". $coinInfo["minimum_amount"] ."-". $coinInfo["maximum_amount"] . " "; 39 | foreach ($coinInfo["exchanges"] as $key => $exchange) { 40 | echo $exchange . " "; 41 | $result .= $exchange . " "; 42 | } 43 | echo PHP_EOL; 44 | $result .= PHP_EOL; 45 | } 46 | } 47 | return $result; 48 | } 49 | // print_r($resInfo["data"]); 50 | // foreach ($resInfo as $coinInfo) { 51 | // echo "e" . PHP_EOL; 52 | // print_r($coinInfo); 53 | // // echo ($coinInfo["exchange_asset"] . $coinInfo["exchange_asset_symbol"] . PHP_EOL); 54 | // } 55 | -------------------------------------------------------------------------------- /others/createUser.php: -------------------------------------------------------------------------------- 1 | Network()->createUser("Tom cat"); 14 | //Create User api include all account information 15 | print_r($tomcat_info); 16 | print($tomcat_info["pubKey"]); 17 | 18 | $newConfig = array(); 19 | $newConfig["private_key"] = $tomcat_info["priKey"]; 20 | $newConfig["pin_token"] = $tomcat_info["pin_token"]; 21 | $newConfig["session_id"] = $tomcat_info["session_id"]; 22 | $newConfig["client_id"] = $tomcat_info["user_id"]; 23 | $newConfig["pin"] = PIN; 24 | //Install the parameter in PHP SDK 25 | $tomcat_instance = new MixinSDK($newConfig); 26 | 27 | //Create a PIN. 28 | $pinInfo = $tomcat_instance->Pin()->updatePin('',PIN); 29 | print_r($pinInfo); 30 | print_r($trans_info); 31 | //Create Bitcoin deposit address by read Bitcoin asset 32 | $asset_infoNew = $tomcat_instance->Wallet()->readAsset(BTC_ASSET_ID); 33 | print_r("BitCoin wallet address is :".$asset_infoNew["public_key"]); 34 | 35 | //Transfer Bitcoin to developer's account, zero fee and confirmed instantly 36 | $trans_info = $bot_instance->Wallet()->transfer(BTC_ASSET_ID,$tomcat_info["client_id"], 37 | $bot_instance->getConfig()['default']['pin'],AMOUNT); 38 | print_r($trans_info); 39 | 40 | //Read user information by ID 41 | $master_userInfo = $bot_instance->Network()->readUser(MASTER_ID); 42 | $master_userInfo["user_id"]; 43 | 44 | $trans_info2 = $tomcat_instance->Wallet()->transfer(BTC_ASSET_ID,$master_userInfo["user_id"], 45 | $account_instance->getConfig()['default']['pin'],AMOUNT); 46 | 47 | print_r($trans_info2); 48 | -------------------------------------------------------------------------------- /others/hardcode.php: -------------------------------------------------------------------------------- 1 | '8.8.8.8', 11 | 'timeout' => 15 12 | ]); 13 | class callTraitClass { 14 | use MixinSDKTrait; 15 | protected $config; 16 | public function __construct() 17 | { 18 | $config = require(__DIR__.'/config.php'); 19 | $this->config = $config; 20 | } 21 | } 22 | $callTrait = new callTraitClass(); 23 | $Token = $callTrait->getToken('GET', '/', ''); 24 | // $Header = 'Authorization'.'Bearer '.$Token; 25 | // print($Header); 26 | $connector = new \Ratchet\Client\Connector($loop,$reactConnector); 27 | // $connector('ws://127.0.0.1:9000', ['protocol' => 'Mixin-Blaze-1'], ['Origin' => 'http://localhost', 28 | $connector('wss://blaze.mixin.one', ['protocol' => 'Mixin-Blaze-1'],[ 29 | 'Authorization' => 'Bearer '.$Token 30 | ]) 31 | ->then(function(Ratchet\Client\WebSocket $conn) { 32 | $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) { 33 | $jsMsg = json_decode(gzdecode($msg)); 34 | if ($jsMsg->action === 'CREATE_MESSAGE') { 35 | echo "\nNeed reply server a receipt!\n"; 36 | $IncomingMsg = ["message_id" => $jsMsg->data->message_id, "status" => "READ"]; 37 | $RspMsg = ["id" => Uuid::uuid4()->toString(), "action" => "ACKNOWLEDGE_MESSAGE_RECEIPT", 38 | "params" => $IncomingMsg]; 39 | $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY); 40 | $conn->send($msg); 41 | if ($jsMsg->data->category === 'PLAIN_TEXT') { 42 | echo "PLAIN_TEXT:".base64_decode($jsMsg->data->data); 43 | } 44 | } 45 | }); 46 | 47 | $conn->on('close', function($code = null, $reason = null) { 48 | echo "Connection closed ({$code} - {$reason})\n"; 49 | }); 50 | /* start listen for the incoming message */ 51 | $message = [ 52 | 'id' => Uuid::uuid4()->toString(), 53 | 'action' => 'LIST_PENDING_MESSAGES', 54 | ]; 55 | print_r(json_encode($message)); 56 | $msg = new Frame(gzencode(json_encode($message)),true,Frame::OP_BINARY); 57 | $conn->send($msg); 58 | // $conn->send(gzencode($msg,1,FORCE_DEFLATE)); 59 | }, function(\Exception $e) use ($loop) { 60 | echo "Could not connect: {$e->getMessage()}\n"; 61 | $loop->stop(); 62 | }); 63 | 64 | $loop->run(); 65 | -------------------------------------------------------------------------------- /others/searchUser.php: -------------------------------------------------------------------------------- 1 | Network()->readUser("37222956"); 6 | $userInfo["user_id"]; 7 | print_r($userInfo); 8 | 9 | 10 | 11 | $asset_infoNew = $mixinSdk->Wallet()->readAsset("c6d0c728-2624-429b-8e0d-d9d19b6592fa"); 12 | 13 | print_r($asset_infoNew); 14 | -------------------------------------------------------------------------------- /others/wrenchClient.php: -------------------------------------------------------------------------------- 1 | sendData('hello,world!'); 10 | } 11 | 12 | $client = new Client('ws://localhost:8080/echo', 13 | 'ws://localhost:8080/echo', 14 | [ 15 | 'on_data_callback' => onData] 16 | ); 17 | // $client = new Client('wss://blaze.mixin.one/', 'https://google.com'); 18 | $client->connect(); 19 | $client->sendData('hello,world!'); 20 | $response = $client->receive()[0]->getPayload(); 21 | 22 | while (true) { 23 | // print('in while'); 24 | sleep(1); 25 | } 26 | $client->disconnect(); 27 | -------------------------------------------------------------------------------- /pay-links.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/pay-links.jpg -------------------------------------------------------------------------------- /php-eth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/php-eth.jpg -------------------------------------------------------------------------------- /res/btc-usdt-price.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/res/btc-usdt-price.jpg -------------------------------------------------------------------------------- /res/exchange-and-balance.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/res/exchange-and-balance.jpg -------------------------------------------------------------------------------- /res/help.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/res/help.jpg -------------------------------------------------------------------------------- /res/user-directly-exchage-result.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/res/user-directly-exchage-result.jpg -------------------------------------------------------------------------------- /res/user-exchange-bitcoin-directly.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenewzhang/mixin_labs-php-bot/76b3945d0b6e89a418f557039585f87e1058e16e/res/user-exchange-bitcoin-directly.jpg -------------------------------------------------------------------------------- /test/call_user_func_example.php: -------------------------------------------------------------------------------- 1 | 2 | 22 | --------------------------------------------------------------------------------