Skip to content

Commit c2dc33a

Browse files
committed
Merge branch 'feature/new-format'
# Conflicts: # tests/Feature/WalletApiTest.php
2 parents abc5665 + b2b8834 commit c2dc33a

File tree

6 files changed

+145
-11
lines changed

6 files changed

+145
-11
lines changed

src/Apis/Api.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ class Api
5454
/**
5555
* Api constructor.
5656
*
57-
* @param $config
58-
* @param string $base_uri
59-
* @param int $timeout
57+
* @param array $config
58+
* @param string|null $base_uri
59+
* @param int|null $timeout
6060
*/
61-
public function __construct($config, string $base_uri = null, int $timeout = null)
61+
public function __construct(array $config, string $base_uri = null, int $timeout = null)
6262
{
6363
$this->packageConfig = require(__DIR__.'/../../config/config.php');
6464

src/Container.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
* @method array safeFetchDepositEntries(string $chain_uuid, array $members, int $threshold): array
9797
* @method array safeReadDeposits(string $asset_uuid = null, string $destination = null, string $tag = null, string $offset = null, int $limit = 500): array
9898
* @method array safeReadOutputs(array $members_array = null, int $threshold = null, int $offset_sequence = null, int $limit = 500, string $asset_hash = null, string $state = null, string $order = 'ASC'): array
99+
* @method array safeReadAssets(): array
99100
* @method array safeFetchKeys(array $receiver_info): array
100101
* @method array safeRequestTransaction(array $transaction, string $request_id): array
101102
* @method array safeSendTransaction(array $transaction, array $views, string $trace_id = null, string $spent_key = null, bool $use_32_bits = false): array
@@ -347,7 +348,7 @@ public function setIterator(array $iterator)
347348
public function boomRoom($errorCode, $description, $extra, $headers = [])
348349
{
349350
$extra = json_encode($extra);
350-
$id = $headers['X-Request-Id'][0] ?? '';
351+
$id = $headers['X-Request-Id'][0] ?? '';
351352
throw new MixinNetworkRequestException("{$description}, {$extra}, {$id}", $errorCode);
352353
}
353354
}

src/MixinSDK.php

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace ExinOne\MixinSDK;
44

5+
use Base64Url\Base64Url;
6+
use ExinOne\MixinSDK\Apis\Api;
57
use ExinOne\MixinSDK\Exceptions\ClassNotFoundException;
68
use ExinOne\MixinSDK\Exceptions\MixinNetworkRequestException;
79
use ExinOne\MixinSDK\Exceptions\NotFoundConfigException;
@@ -48,7 +50,7 @@ public function __construct(array $config = [])
4850
if (is_array($config['keys'] ?? 'e')) {
4951
$this->config = $config['keys'];
5052
} else {
51-
$this->config[$this->useConfigName] = $config;
53+
$this->config[$this->useConfigName] = self::configParser($config);
5254
}
5355
$this->base_uri = $config['base_uri'] ?? null;
5456
$this->timeout = $config['timeout'] ?? null;
@@ -103,7 +105,7 @@ public function use(string $name, array $config = [], string $base_uri = null, i
103105
{
104106
$this->useConfigName = $name;
105107
if (! empty($config)) {
106-
$this->config[$name] = $config;
108+
$this->config[$name] = self::configParser($config);
107109
}
108110
if ($base_uri) {
109111
$this->base_uri = $base_uri;
@@ -124,7 +126,7 @@ public function use(string $name, array $config = [], string $base_uri = null, i
124126
*/
125127
public function setConfig(string $name, array $config, string $base_uri = null, int $timeout = null)
126128
{
127-
$this->config[$name] = $config;
129+
$this->config[$name] = self::configParser($config);
128130
if ($base_uri) {
129131
$this->base_uri = $base_uri;
130132
}
@@ -195,4 +197,39 @@ public static function createEd25519PrivateKey(): string
195197
{
196198
return TIPService::createEd25519PrivateKey();
197199
}
200+
201+
public static function configParser(array $config): array
202+
{
203+
// 检查是否是新版包含server_public_key的配置格式,并尝试将其转成旧版格式
204+
if (isset($config['server_public_key']) && isset($config['session_private_key'])) {
205+
return [
206+
'mixin_id' => $config['mixin_id'] ?? '',
207+
'client_id' => $config['app_id'] ?? '',
208+
'client_secret' => $config['client_secret'] ?? '',
209+
'pin' => '000000', // 不再需要 PIN,但为了兼容目前的校验逻辑不能留空
210+
'pin_token' => Base64Url::encode(
211+
sodium_crypto_sign_ed25519_sk_to_curve25519(
212+
TIPService::getSecretKeyFromSeed(
213+
hex2bin($config['server_public_key'])
214+
)
215+
)
216+
),
217+
'session_id' => $config['session_id'] ?? '',
218+
'private_key' => Base64Url::encode(
219+
TIPService::getSecretKeyFromSeed(
220+
hex2bin($config['session_private_key'])
221+
)
222+
),
223+
'safe_key' => isset($config['spend_key'])
224+
? Base64Url::encode(
225+
sodium_crypto_sign_seed_keypair(
226+
hex2bin($config['spend_key'])
227+
)
228+
)
229+
: '',
230+
];
231+
}
232+
233+
return $config;
234+
}
198235
}

src/Utils/TIPService.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,9 @@ public static function getPublicKeyFromEd25519KeyPair(string $bin_seed, bool $us
140140
Ed25519::ge_scalarmult_base($bin_seed)
141141
);
142142
}
143+
144+
public static function getSecretKeyFromSeed(string $seed): string
145+
{
146+
return sodium_crypto_sign_secretkey(sodium_crypto_sign_seed_keypair($seed));
147+
}
143148
}

tests/Feature/NetworkApiTest.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
class NetworkApiTest extends TestCase
1515
{
1616
protected $mixinSDK;
17+
protected $mixin_sdk_server_public;
1718

1819
public function __construct(string $name = null, array $data = [], string $dataName = '')
1920
{
2021
parent::__construct($name, $data, $dataName);
21-
$this->mixinSDK = new MixinSDK(require './testKeys.php');
22+
$this->mixinSDK = new MixinSDK(require 'test_keys_ed25519.php');
23+
$this->mixin_sdk_server_public = new MixinSDK(require 'test_keys_server_public.php');
2224
}
2325

2426
public function test_it_can_read_user_success0()
@@ -28,6 +30,13 @@ public function test_it_can_read_user_success0()
2830
self::assertFalse(false);
2931
}
3032

33+
public function test_server_public_read_user_success0()
34+
{
35+
$userInfo = $this->mixin_sdk_server_public->network()->readUser('36d51948-4a0d-400a-80de-f71070e374c0');
36+
dump($userInfo);
37+
self::assertFalse(false);
38+
}
39+
3140
public function test_it_can_read_users_success0()
3241
{
3342

tests/Feature/WalletApiTest.php

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@ class WalletApiTest extends TestCase
2222

2323
protected $mixin_sdk_safe;
2424

25+
protected $mixin_sdk_server_public;
26+
2527
public function __construct(?string $name = null, array $data = [], string $dataName = '')
2628
{
2729
parent::__construct($name, $data, $dataName);
28-
$this->mixin_sdk = new MixinSDK(require 'test_keys_ed25519.php');
29-
$this->mixin_sdk_safe = new MixinSDK(require 'test_safe_keys.php');
30+
$this->mixin_sdk = new MixinSDK(require 'test_keys_ed25519.php');
31+
$this->mixin_sdk_safe = new MixinSDK(require 'test_safe_keys.php');
32+
$this->mixin_sdk_server_public = new MixinSDK(require 'test_keys_server_public.php');
3033
}
3134

3235
public function test_it_can_create_address_success0()
@@ -396,6 +399,76 @@ public function test_safe_mainnet_transfer_success()
396399
dump('send transaction', $res);
397400
}
398401

402+
public function test_server_public_safe_mainnet_transfer_success()
403+
{
404+
$asset_hash = '6d2a7b89fcaca190f711043aeb5d6c274d6db49900257c1bd2e91aa24185d10c'; // asset ROAY
405+
$res = $this->mixin_sdk_server_public->wallet()->safeReadOutputs([$this->mixin_sdk_server_public->config['default']['client_id']], 1, null, 10, $asset_hash, 'unspent');
406+
dump($res);
407+
$input = $res[0];
408+
409+
$data = [
410+
[
411+
'receivers' => ['2ef7c59f-bf5c-41b3-bb67-2d2c4d6b925c'],
412+
'index' => 0,
413+
'hint' => Uuid::uuid4()->toString(),
414+
],
415+
[
416+
'receivers' => [$this->mixin_sdk_server_public->config['default']['client_id']],
417+
'index' => 1,
418+
'hint' => Uuid::uuid4()->toString(),
419+
],
420+
];
421+
422+
$keys = $this->mixin_sdk_server_public->wallet()->safeFetchKeys($data);
423+
424+
dump('ghost keys', $keys);
425+
426+
$transfer_amount = '1.1';
427+
428+
$transaction = [
429+
'version' => 5,
430+
'asset' => $asset_hash,
431+
'extra' => bin2hex('test'), // <= 512
432+
'outputs' => [
433+
[
434+
'type' => 0,
435+
'amount' => $transfer_amount,
436+
//todo 收款人长度超过10的话待测试
437+
'script' => "fffe0".count($data[0]['receivers']),
438+
'keys' => $keys[0]['keys'],
439+
'mask' => $keys[0]['mask'],
440+
],
441+
[
442+
'type' => 0,
443+
'amount' => (string)BigDecimal::of($input['amount'])->minus($transfer_amount)->stripTrailingZeros(),
444+
'script' => "fffe0".count($data[1]['receivers']),
445+
'keys' => $keys[1]['keys'],
446+
'mask' => $keys[1]['mask'],
447+
]
448+
],
449+
'inputs' => [
450+
[
451+
'hash' => $input['transaction_hash'],
452+
'index' => $input['output_index'],
453+
]
454+
],
455+
];
456+
457+
dump('transaction', $transaction);
458+
459+
$request_id = Uuid::uuid4()->toString();
460+
461+
$trans = $this->mixin_sdk_server_public->wallet()->safeRequestTransaction($transaction, $request_id);
462+
463+
dump('request transaction', $trans);
464+
465+
self::assertEquals($trans[0]['request_id'], $request_id);
466+
467+
$res = $this->mixin_sdk_server_public->wallet()->setRaw(true)->safeSendTransaction($transaction, $trans[0]['views'], $request_id);
468+
469+
dump('send transaction', $res);
470+
}
471+
399472
public function test_sign_mixin_ed25519()
400473
{
401474
$transaction = [
@@ -454,6 +527,15 @@ public function test_safe_read_assets_success()
454527
self::assertIsArray($res);
455528
}
456529

530+
public function test_server_public_safe_read_assets_success()
531+
{
532+
$res = $this->mixin_sdk_server_public->wallet()->safeReadAssets();
533+
534+
dump($res);
535+
536+
self::assertIsArray($res);
537+
}
538+
457539
public function test_safe_read_asset_success()
458540
{
459541
$res = $this->mixin_sdk_safe->wallet()->safeReadAsset('b91e18ff-a9ae-3dc7-8679-e935d9a4b34b');

0 commit comments

Comments
 (0)