handshake = $handshake; $this->request = $request; return 'ok'; } }; $crypto = new CallbackCrypto( fn (string $message): string => str_repeat("\x11", 32), fn (string $message, string $privateKey, string $publicKey): string => str_repeat("\x22", 666), fn (string $message, string $signature, string $publicKey): bool => true, ); $credentials = new Credentials(str_repeat("\x33", 897), str_repeat("\x44", 1281)); $client = new Client($transport, $crypto, $credentials); expect($client->blockByHeight(42) === 'ok', 'Client did not return the RPC payload.'); expect(strlen($transport->handshake) === 1587, 'Handshake request has the wrong size.'); expect(substr($transport->handshake, 0, 2) === "\xac\xed", 'Handshake marker is wrong.'); expect(ord($transport->request[0]) === Command::BLOCK_BY_HEIGHT, 'RPC command is wrong.'); expect(unpack('Vheight', substr($transport->request, 4, 4))['height'] === 42, 'Height encoding is wrong.'); $client->storageLookupCost(str_repeat('01', 32), 'all', str_repeat('ab', 20) . '.cltc'); expect(ord($transport->request[0]) === Command::STORAGE_LOOKUP_COST, 'Storage command is wrong.'); expect(strlen($transport->request) === 4 + 32 + 50 + 22, 'Storage cost payload has the wrong size.'); $client->registerOwnedWallet(str_repeat('ab', 20) . '.cltc'); expect(ord($transport->request[0]) === Command::REGISTER_WALLET, 'Wallet registration command is wrong.'); expect(strlen($transport->request) === 4 + 22 + 897 + 666, 'Wallet registration payload has the wrong size.'); $transfer = (new TransferBuilder($crypto, $credentials))->create( str_repeat('ab', 20) . '.cltc', str_repeat('cd', 20) . '.cltc', 'CLTC', 2_500_000, 2_500, timestamp: 1_700_000_000, ); expect(strlen($transfer->bytes) === 750, 'Transfer transaction has the wrong byte size.'); expect( $transfer->unsignedJson === '{"txtype":2,"time":1700000000,"value":2500000,"coin":"CLTC ","nft_series":0,"sender":"' . str_repeat('ab', 20) . '.cltc","receiver":"' . str_repeat('cd', 20) . '.cltc","txfee":2500}', 'Transfer signing JSON does not match Rust struct serialization.', ); $address = str_repeat('ab', 20) . '.cltc'; $assets = new AssetBuilder($crypto, $credentials); expect(strlen($assets->createToken($address, 'TEST', 1000, true, 100, 1)->bytes) === 725, 'Token size is wrong.'); expect(strlen($assets->issueToken($address, 'TEST', 1000, 100, 1)->bytes) === 724, 'Token issue size is wrong.'); expect(strlen($assets->createNft($address, false, false, 'ART', 'cid', 1, 'description', 100, 1)->bytes) === 922, 'NFT size is wrong.'); expect(strlen($assets->burn($address, 'TEST', 0, 1, 100, 1)->bytes) === 728, 'Burn size is wrong.'); expect(strlen($assets->vanity($address, str_repeat('a', 20) . '.cltc', 100, 1)->bytes) === 723, 'Vanity size is wrong.'); $governance = new GovernanceBuilder($crypto, $credentials); expect(strlen($governance->proposal(str_repeat('01', 32), $address, 100, 1)->bytes) === 733, 'Proposal size is wrong.'); expect(strlen($governance->proposalVote(str_repeat('01', 32), $address, true, 100, 1)->bytes) === 734, 'Proposal vote size is wrong.'); expect(strlen($governance->activationVote(str_repeat('01', 32), str_repeat('02', 32), 'CLP-0001.md', $address, true, 100, 1)->bytes) === 866, 'Activation vote size is wrong.'); $storage = new StorageBuilder($crypto, $credentials); expect(strlen($storage->createKey($address, 100, 1)->bytes) === 701, 'Storage key size is wrong.'); expect(strlen($storage->boolean(str_repeat('01', 32), 'active', true, $address, 100, 1)->bytes) === 784, 'Storage bool size is wrong.'); expect(strlen($storage->u32(str_repeat('01', 32), 'count', 42, $address, 100, 1)->bytes) === 787, 'Storage u32 size is wrong.'); expect(strlen($storage->i64(str_repeat('01', 32), 'balance', -42, $address, 100, 1)->bytes) === 791, 'Storage i64 size is wrong.'); expect(strlen($storage->u128(str_repeat('01', 32), 'large', '340282366920938463463374607431768211455', $address, 100, 1)->bytes) === 799, 'Storage u128 size is wrong.'); expect(strlen($storage->i128(str_repeat('01', 32), 'negative', '-170141183460469231731687303715884105728', $address, 100, 1)->bytes) === 799, 'Storage i128 size is wrong.'); expect(bin2hex(substr($storage->u128(str_repeat('01', 32), 'large', '340282366920938463463374607431768211455', $address, 100, 1)->bytes, 87, 16)) === str_repeat('ff', 16), 'u128 maximum encoding is wrong.'); expect(strlen($storage->string(str_repeat('01', 32), 'bio', 'hello', $address, str_repeat('0', 64), 100, 1)->bytes) === 995, 'Storage string size is wrong.'); expect(strlen($storage->delete(str_repeat('01', 32), 'bio', $address, 100, 1)->bytes) === 783, 'Storage delete size is wrong.'); $misc = new MiscellaneousBuilder($crypto, $credentials); expect(strlen($misc->marketing(1, 'banner', 'keyword', 'website', 1, 1, 100, 100, $address, 100, 1)->bytes) === 861, 'Marketing size is wrong.'); expect(strlen($misc->collateralClaim(str_repeat('01', 32), $address, 100, 1)->bytes) === 733, 'Collateral claim size is wrong.'); expect(strlen($misc->loanPayment(1000, str_repeat('01', 32), $address, 100, 100, 1)->bytes) === 781, 'Loan payment size is wrong.'); $agreements = new AgreementBuilder($crypto, $credentials); $swap = $agreements->swap(1000, 'CLTC', 0, 100, 'TEST', 0, 200, $address, str_repeat('cd', 20) . '.cltc', 1, 2, 3, 4, 1); $swap = $swap->signNext($crypto, $credentials); expect(strlen($swap->toSignedTransaction()->bytes) === 1471, 'Swap size is wrong.'); expect(DualSignedTransaction::import($swap->export())->isComplete(), 'Swap export/import lost signatures.'); $loan = $agreements->loan('CLTC', 1000, $address, 'TEST', 2000, str_repeat('cd', 20) . '.cltc', 'm', 12, 100, 2, 300, 100, 1); $loan = $loan->signNext($crypto, $credentials); expect(strlen($loan->toSignedTransaction()->bytes) === 1492, 'Loan size is wrong.'); echo "All protocol tests passed.\n";