Skip to content

Commit

Permalink
feat: accept pubkey in Wallet.new
Browse files Browse the repository at this point in the history
  • Loading branch information
classicalliu committed Jun 6, 2019
1 parent 6702874 commit c175710
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 19 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ tx_hash = bob.send_capacity(alice.address, 1000 * 10**8)
api.get_transaction(tx_hash)
```

Provide wallet a public key

```ruby
api = CKB::API.new

bob = CKB::Wallet.new(api, "0x024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01")
alice = CKB::Wallet.new(api, "0x0257623ec521657a27204c5590384cd59d9267c06d75ab308070be692251b67c57")

bob_key = "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3"

tx_hash = bob.send_capacity(alice.address, 1000 * 10**8, key: bob_key)
```

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
Expand Down
84 changes: 65 additions & 19 deletions lib/ckb/wallet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,24 @@ module CKB

class Wallet
attr_reader :api
# privkey is a bin string
attr_reader :key
attr_reader :pubkey
attr_reader :addr
attr_reader :address

# @param api [CKB::API]
# @param key [CKB::Key]
# @param key [CKB::Key | String] Key or pubkey
def initialize(api, key)
@api = api
@key = key
if key.is_a?(CKB::Key)
@key = key
@pubkey = @key.pubkey
else
@pubkey = key
@key = nil
end
@addr = Address.from_pubkey(@pubkey)
@address = @addr.to_s
end

def self.from_hex(api, privkey)
Expand All @@ -45,12 +55,18 @@ def get_balance
get_unspent_cells.map { |cell| cell.capacity.to_i }.reduce(0, &:+)
end

def generate_tx(target_address, capacity, data = "0x")
# @param target_address [String]
# @param capacity [Integer]
# @param data [String ] "0x..."
# @param key [CKB::Key | String] Key or private key hex string
def generate_tx(target_address, capacity, data = "0x", key: nil)
key = get_key(key)

output = Types::Output.new(
capacity: capacity,
data: data,
lock: Types::Script.generate_lock(
key.address.parse(target_address),
addr.parse(target_address),
api.system_script_code_hash
)
)
Expand Down Expand Up @@ -86,15 +102,22 @@ def generate_tx(target_address, capacity, data = "0x")
# @param target_address [String]
# @param capacity [Integer]
# @param data [String] "0x..."
def send_capacity(target_address, capacity, data = "0x")
tx = generate_tx(target_address, capacity, data)
# @param key [CKB::Key | String] Key or private key hex string
def send_capacity(target_address, capacity, data = "0x", key: nil)
tx = generate_tx(target_address, capacity, data, key: key)
send_transaction(tx)
end

def deposit_to_dao(capacity)
# @param capacity [Integer]
# @param key [CKB::Key | String] Key or private key hex string
#
# @return [CKB::Type::OutPoint]
def deposit_to_dao(capacity, key: nil)
key = get_key(key)

output = Types::Output.new(
capacity: capacity,
lock: Types::Script.generate_lock(@key.address.blake160, DAO_CODE_HASH)
lock: Types::Script.generate_lock(addr.blake160, DAO_CODE_HASH)
)

charge_output = Types::Output.new(
Expand Down Expand Up @@ -126,7 +149,13 @@ def deposit_to_dao(capacity)
Types::OutPoint.new(cell: Types::CellOutPoint.new(tx_hash: tx_hash, index: 0))
end

def generate_withdraw_from_dao_transaction(cell_out_point)
# @param cell_out_point [CKB::Type::OutPoint]
# @param key [CKB::Key | String] Key or private key hex string
#
# @return [CKB::Type::Transaction]
def generate_withdraw_from_dao_transaction(cell_out_point, key: nil)
key = get_key(key)

cell_status = api.get_live_cell(cell_out_point)
unless cell_status.status == "live"
raise "Cell is not yet live!"
Expand Down Expand Up @@ -188,10 +217,6 @@ def block_assembler_config
).strip
end

def address
@key.address.to_s
end

private

# @param transaction [CKB::Transaction]
Expand Down Expand Up @@ -225,20 +250,41 @@ def gather_inputs(capacity, min_capacity, min_charge_capacity)
OpenStruct.new(inputs: inputs, capacities: input_capacities, witnesses: witnesses)
end

def pubkey
@key.pubkey
end

def lock_hash
@lock_hash ||= lock.to_hash
end

# @return [CKB::Types::Script]
def lock
Types::Script.generate_lock(
@key.address.blake160,
addr.blake160,
api.system_script_code_hash
)
end

# @param [CKB::Key | String | nil]
#
# @return [CKB::Key]
def get_key(key)
raise "Must provide a private key" unless @key || key

return @key if @key

the_key = convert_key(key)
raise "Key not match pubkey" unless the_key.pubkey == @pubkey

the_key
end

# @param key [CKB::Key | String] a Key or private key hex string
#
# @return [CKB::Key]
def convert_key(key)
return if key.nil?

return key if key.is_a?(CKB::Key)

CKB::Key.new(key)
end
end
end
85 changes: 85 additions & 0 deletions spec/ckb/wallet_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
RSpec.describe CKB::Wallet do
let(:privkey) { "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3" }
let(:key) { CKB::Key.new(privkey) }
let(:pubkey) { key.pubkey }
let(:api) { nil }

context "initialize" do
it "Key" do
wallet = CKB::Wallet.new(api, key)

expect(wallet.key.privkey).to eq key.privkey
expect(wallet.pubkey).to eq key.pubkey
expect(wallet.address).to eq key.address.to_s
end

it "pubkey" do
wallet = CKB::Wallet.new(api, pubkey)

expect(wallet.key).to be nil
expect(wallet.pubkey).to eq pubkey
expect(wallet.address).to eq key.address.to_s
end
end

it "self.from_hex" do
wallet = CKB::Wallet.from_hex(api, privkey)

expect(wallet.key.privkey).to eq privkey
end

context "convert_key" do
let(:wallet) { CKB::Wallet.new(api, pubkey) }
it "nil" do
expect(
wallet.send(:convert_key, nil)
).to be nil
end

it "Key" do
expect(
wallet.send(:convert_key, key)
).to be key
end

it "privkey" do
expect(
wallet.send(:convert_key, privkey)
).to be_a(CKB::Key)
end
end

context "get_key" do
context "key exists" do
let(:wallet) { CKB::Wallet.new(api, key) }

it "return @key" do
the_key = wallet.send(:get_key, key)

expect(the_key).to be wallet.key
end
end

context "key not exists" do
let(:wallet) { CKB::Wallet.new(api, pubkey) }

it "nil" do
expect {
wallet.send(:get_key, nil)
}.to raise_error(RuntimeError)
end

it "Key" do
expect(
wallet.send(:get_key, key)
).to eq key
end

it "privkey" do
expect(
wallet.send(:get_key, privkey)
).to be_a(CKB::Key)
end
end
end
end

0 comments on commit c175710

Please sign in to comment.