From ca76f06cda82623ca48b3d623da6f2c5cb2851c6 Mon Sep 17 00:00:00 2001 From: AhsanJavaid Date: Wed, 26 Jan 2022 18:51:58 +0500 Subject: [PATCH] fix: add preorder name command in cli --- packages/cli/src/argparse.ts | 32 +++++++---- packages/cli/src/cli.ts | 38 ++++++++++++- packages/cli/tests/cli.test.ts | 53 ++++++++++--------- .../tests/fee-estimate/test-fee-estimate.json | 25 +++++++++ 4 files changed, 110 insertions(+), 38 deletions(-) create mode 100644 packages/cli/tests/fee-estimate/test-fee-estimate.json diff --git a/packages/cli/src/argparse.ts b/packages/cli/src/argparse.ts index 4b42b2e1a..6361430b6 100644 --- a/packages/cli/src/argparse.ts +++ b/packages/cli/src/argparse.ts @@ -2465,26 +2465,30 @@ export const CLI_ARGS = { type: 'array', items: [ { - name: 'blockstack_id', + name: 'fully-qualified-name', type: 'string', - realtype: 'on-chain-blockstack_id', + realtype: 'on-chain-fully-qualified-name', pattern: NAME_PATTERN, }, - { - name: 'id_address', - type: 'string', - realtype: 'id-address', - pattern: ID_ADDRESS_PATTERN, - }, { name: 'payment_key', type: 'string', realtype: 'private_key', pattern: `${PRIVATE_KEY_PATTERN_ANY}`, }, + { + name: 'salt', + type: 'string', + realtype: 'text', + }, + { + name: 'stx_to_burn', + type: 'string', + realtype: 'number', + }, ], - minItems: 3, - maxItems: 3, + minItems: 4, + maxItems: 4, help: 'Generate and send `NAME_PREORDER` transaction, for a Blockstack ID to be owned ' + 'by a given `ID_ADDRESS`. The name cost will be paid for by the gven `PAYMENT_KEY`. The ' + @@ -2492,7 +2496,13 @@ export const CLI_ARGS = { 'generating the name preorder hash.\n' + '\n' + 'This is a low-level command that only experienced Blockstack developers should use. ' + - 'If you just want to register a name, use the "register" command.\n', + 'If you just want to register a name, use the "register" command.\n' + + '\n' + + 'Example:\n' + + '\n' + + ' $ export PAYMENT="136ff26efa5db6f06b28f9c8c7a0216a1a52598045162abfe435d13036154a1b01"\n' + + ' $ stx tx_preorder example.id "$PAYMENT" salt 1000' + + '\n', group: 'Blockstack ID Management', }, tx_register: { diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index a8f772a67..61e1e732c 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -43,7 +43,7 @@ import { createStacksPrivateKey, AnchorMode, } from '@stacks/transactions'; -import { buildRegisterNameTx } from '@stacks/bns'; +import { buildPreorderNameTx, buildRegisterNameTx } from '@stacks/bns'; import { StacksMainnet, StacksTestnet } from '@stacks/network'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -1687,6 +1687,40 @@ async function register(network: CLINetworkAdapter, args: string[]): Promise { + const fullyQualifiedName = args[0]; + const privateKey = args[1]; + const salt = args[2]; + const stxToBurn = args[3]; + const publicKey = publicKeyToString(pubKeyfromPrivKey(privateKey)); + const txNetwork = network.isMainnet() ? new StacksMainnet() : new StacksTestnet(); + + const unsignedTransaction = await buildPreorderNameTx({ + fullyQualifiedName, + publicKey, + salt, + stxToBurn, + network: txNetwork, + }); + + const signer = new TransactionSigner(unsignedTransaction); + signer.signOrigin(createStacksPrivateKey(privateKey)); + + return broadcastTransaction(signer.transaction, txNetwork) + .then((response: TxBroadcastResult) => { + if (response.hasOwnProperty('error')) { + return response; + } + return { + txid: `0x${response.txid}`, + transaction: generateExplorerTxPageUrl(response.txid, txNetwork), + }; + }) + .catch(error => { + return error; + }); +} + function faucetCall(_: CLINetworkAdapter, args: string[]): Promise { const address = args[0]; // console.log(address); @@ -1799,6 +1833,7 @@ const COMMANDS: Record = { profile_verify: profileVerify, // 'send_btc': sendBTC, register: register, + tx_preorder: preorder, send_tokens: sendTokens, stack: stack, stacking_status: stackingStatus, @@ -1977,5 +2012,6 @@ export const testables = makeKeychain, getStacksWalletKey, register, + preorder, } : undefined; diff --git a/packages/cli/tests/cli.test.ts b/packages/cli/tests/cli.test.ts index 20ddf76b9..092b65113 100644 --- a/packages/cli/tests/cli.test.ts +++ b/packages/cli/tests/cli.test.ts @@ -11,9 +11,10 @@ import fetchMock from 'jest-fetch-mock'; import { makekeychainTests, keyInfoTests, MakeKeychainResult, WalletKeyInfoResult } from './derivation-path/keychain'; const TEST_ABI: ClarityAbi = JSON.parse(readFileSync(path.join(__dirname, './abi/test-abi.json')).toString()); +const TEST_FEE_ESTIMATE = JSON.parse(readFileSync(path.join(__dirname, './fee-estimate/test-fee-estimate.json')).toString()); jest.mock('inquirer'); -const { addressConvert, contractFunctionCall, makeKeychain, getStacksWalletKey, register } = testables as any; +const { addressConvert, contractFunctionCall, makeKeychain, getStacksWalletKey, preorder, register } = testables as any; const mainnetNetwork = new CLINetworkAdapter( getNetwork({} as CLI_CONFIG_TYPE, false), @@ -231,31 +232,7 @@ describe('BNS', () => { zonefile, ]; - const mockedResponse = JSON.stringify({ - cost_scalar_change_by_byte: 0.00476837158203125, - estimated_cost: { - read_count: 19, - read_length: 4814, - runtime: 7175000, - write_count: 2, - write_length: 1020 - }, - estimated_cost_scalar: 14, - estimations: [ - { - fee: 200, - fee_rate: 10 - }, - { - fee: 180, - fee_rate: 1.2410714285714286 - }, - { - fee: 160, - fee_rate: 8.958333333333332 - }, - ] - }); + const mockedResponse = JSON.stringify(TEST_FEE_ESTIMATE); fetchMock.mockOnce(mockedResponse); fetchMock.mockOnce(JSON.stringify({ nonce: 1000 })); @@ -265,4 +242,28 @@ describe('BNS', () => { expect(txResult.txid).toEqual('0xsuccess'); }); + + test('buildPreorderNameTx', async () => { + const fullyQualifiedName = 'test.id'; + const privateKey = '0d146cf7289dd0b6f41385b0dbc733167c5dffc6534c59cafd63a615f59095d8'; + const salt = 'salt'; + const stxToBurn = '1000'; + + const args = [ + fullyQualifiedName, + privateKey, + salt, + stxToBurn, + ]; + + const mockedResponse = JSON.stringify(TEST_FEE_ESTIMATE); + + fetchMock.mockOnce(mockedResponse); + fetchMock.mockOnce(JSON.stringify({ nonce: 1000 })); + fetchMock.mockOnce(JSON.stringify('success')); + + const txResult = await preorder(testnetNetwork, args); + + expect(txResult.txid).toEqual('0xsuccess'); + }); }); diff --git a/packages/cli/tests/fee-estimate/test-fee-estimate.json b/packages/cli/tests/fee-estimate/test-fee-estimate.json new file mode 100644 index 000000000..1b0fc9234 --- /dev/null +++ b/packages/cli/tests/fee-estimate/test-fee-estimate.json @@ -0,0 +1,25 @@ +{ + "cost_scalar_change_by_byte": 0.00476837158203125, + "estimated_cost": { + "read_count": 19, + "read_length": 4814, + "runtime": 7175000, + "write_count": 2, + "write_length": 1020 + }, + "estimated_cost_scalar": 14, + "estimations": [ + { + "fee": 200, + "fee_rate": 10 + }, + { + "fee": 180, + "fee_rate": 1.2410714285714286 + }, + { + "fee": 160, + "fee_rate": 8.958333333333332 + } + ] +}