Class: Hyperliquid::Signer

Inherits:
Object
  • Object
show all
Defined in:
lib/hyperliquid/signer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(private_key:, base_url: MAINNET_URL) ⇒ Signer

Returns a new instance of Signer.

Parameters:

  • private_key (String)

    hex private key (with or without 0x prefix)

  • base_url (String) (defaults to: MAINNET_URL)

    API URL to determine mainnet vs testnet



12
13
14
15
16
# File 'lib/hyperliquid/signer.rb', line 12

def initialize(private_key:, base_url: MAINNET_URL)
  hex = private_key.delete_prefix("0x")
  @key = Eth::Key.new(priv: hex)
  @is_mainnet = base_url == MAINNET_URL
end

Instance Attribute Details

#is_mainnetObject (readonly)

Returns the value of attribute is_mainnet.



8
9
10
# File 'lib/hyperliquid/signer.rb', line 8

def is_mainnet
  @is_mainnet
end

#keyObject (readonly)

Returns the value of attribute key.



8
9
10
# File 'lib/hyperliquid/signer.rb', line 8

def key
  @key
end

Instance Method Details

#action_hash(action, nonce:, vault_address: nil, expires_after: nil) ⇒ Object

Compute the action hash for L1 actions. msgpack(action) + nonce(8B) + vault_flag(1B) + [vault_addr(20B)] + [0x00 + expires(8B)]



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/hyperliquid/signer.rb', line 56

def action_hash(action, nonce:, vault_address: nil, expires_after: nil)
  data = MessagePack.pack(action)
  data += [nonce].pack("Q>")

  if vault_address.nil?
    data += "\x00".b
  else
    data += "\x01".b
    data += Utils.address_to_bytes(vault_address)
  end

  if expires_after
    data += "\x00".b
    data += [expires_after].pack("Q>")
  end

  Eth::Util.keccak256(data)
end

#addressObject



18
19
20
# File 'lib/hyperliquid/signer.rb', line 18

def address
  @key.address.to_s
end

#sign_l1_action(action, nonce:, vault_address: nil, expires_after: nil) ⇒ Object

Sign an L1 action (orders, cancels, leverage, etc.) Returns { r: “0x…”, s: “0x…”, v: Integer }



24
25
26
27
28
29
# File 'lib/hyperliquid/signer.rb', line 24

def sign_l1_action(action, nonce:, vault_address: nil, expires_after: nil)
  hash = action_hash(action, nonce: nonce, vault_address: vault_address, expires_after: expires_after)
  phantom = { source: (@is_mainnet ? "a" : "b"), connectionId: hash }
  typed_data = build_agent_typed_data(phantom)
  sign_typed_data(typed_data)
end

#sign_multi_sig_action(action, nonce:, vault_address: nil, expires_after: nil) ⇒ Object

Sign a multi-sig action envelope. The inner action hash is used with the SendMultiSig type.



45
46
47
48
49
50
51
52
# File 'lib/hyperliquid/signer.rb', line 45

def sign_multi_sig_action(action, nonce:, vault_address: nil, expires_after: nil)
  inner_action = action["payload"]["action"]
  inner_hash = action_hash(inner_action, nonce: nonce, vault_address: vault_address, expires_after: expires_after)

  phantom = { source: (@is_mainnet ? "a" : "b"), connectionId: inner_hash }
  typed_data = build_agent_typed_data(phantom)
  sign_typed_data(typed_data)
end

#sign_user_signed_action(action, primary_type:, payload_types:) ⇒ Object

Sign a user-signed action (transfers, withdrawals, approvals, etc.)

Parameters:

  • action (Hash)

    the action payload (string keys, will be modified)

  • primary_type (String)

    e.g. “UsdSend”, “Withdraw”

  • payload_types (Array)

    EIP-712 field definitions for the primary type



35
36
37
38
39
40
41
# File 'lib/hyperliquid/signer.rb', line 35

def sign_user_signed_action(action, primary_type:, payload_types:)
  action["signatureChainId"] = "0x66eee"
  action["hyperliquidChain"] = @is_mainnet ? "Mainnet" : "Testnet"

  typed_data = build_user_signed_typed_data(action, primary_type: primary_type, payload_types: payload_types)
  sign_typed_data(typed_data)
end