Class: Privy::Services::Wallets

Inherits:
Resources::Wallets show all
Defined in:
lib/privy/public_api/services/wallets.rb

Instance Attribute Summary collapse

Attributes inherited from Resources::Wallets

#actions, #balance, #swap, #transactions

Instance Method Summary collapse

Methods inherited from Resources::Wallets

#_init_import, #_submit_import, #_transfer, #archive, #authenticate_with_jwt, #create_batch, #create_wallets_with_recovery, #get, #get_wallet_by_address, #list

Constructor Details

#initialize(client:, privy_client:) ⇒ Wallets

Returns a new instance of Wallets.



14
15
16
17
18
19
# File 'lib/privy/public_api/services/wallets.rb', line 14

def initialize(client:, privy_client:)
  super(client: client)
  @privy_client = privy_client
  @earn = Privy::Services::Earn.new(client: client, privy_client: privy_client)
  @tron = Privy::Services::Tron.new(wallets: self)
end

Instance Attribute Details

#earnPrivy::Services::Earn (readonly)



9
10
11
# File 'lib/privy/public_api/services/wallets.rb', line 9

def earn
  @earn
end

#privy_clientObject (readonly)

Returns the value of attribute privy_client.



6
7
8
# File 'lib/privy/public_api/services/wallets.rb', line 6

def privy_client
  @privy_client
end

#tronPrivy::Services::Tron (readonly)



12
13
14
# File 'lib/privy/public_api/services/wallets.rb', line 12

def tron
  @tron
end

Instance Method Details

#create(wallet_create_params:, idempotency_key: nil, request_options: nil) ⇒ Privy::Models::Wallet

Create a new wallet on the requested chain and for the requested owner.

Examples:

Create an ownerless Ethereum wallet

client.wallets.create(wallet_create_params: {chain_type: :ethereum})

Create a wallet with a P-256 key owner

client.wallets.create(wallet_create_params: {
  chain_type: :ethereum,
  owner: {public_key: base64_p256_public_key}
})

Parameters:

  • wallet_create_params (Hash)

    Body parameters for wallet creation.

  • idempotency_key (String, nil) (defaults to: nil)

    Ensures the request is executed only once.

  • request_options (Privy::RequestOptions, Hash, nil) (defaults to: nil)

    Transport-level config (timeouts, retries).

Options Hash (wallet_create_params:):

  • :chain_type (Symbol)

    The wallet chain type (required).

  • :owner (Hash, nil)

    Owner specified as user_id: or public_key:.

  • :owner_id (String, nil)

    Key quorum ID to set as owner.

  • :policy_ids (Array<String>, nil)

    Up to one policy ID to enforce.

  • :display_name (String, nil)

    A human-readable label for the wallet.

  • :external_id (String, nil)

    Customer-provided identifier for external mapping.

  • :additional_signers (Array<Hash>, nil)

    Additional signers for the wallet.

Returns:



44
45
46
47
48
# File 'lib/privy/public_api/services/wallets.rb', line 44

def create(wallet_create_params:, idempotency_key: nil, request_options: nil)
  combined_params = wallet_create_params.merge(request_options: request_options)
  combined_params[:privy_idempotency_key] = idempotency_key if idempotency_key
  super(combined_params)
end

#export(wallet_id, export_seed_phrase: nil, authorization_context: nil, request_expiry: nil, request_options: nil) ⇒ Hash

Export a wallet's private key or seed phrase via HPKE.

Parameters:

  • wallet_id (String)

    ID of the wallet to export.

  • export_seed_phrase (Boolean, nil) (defaults to: nil)

    Whether to export the seed phrase instead of the private key.

  • authorization_context (Privy::Authorization::AuthorizationContext, nil) (defaults to: nil)

    Authorization context for owned wallets.

  • request_expiry (Integer, nil) (defaults to: nil)

    Absolute Unix-ms timestamp at which the request expires.

  • request_options (Privy::RequestOptions, Hash, nil) (defaults to: nil)

    Transport-level config (timeouts, retries).

Returns:

  • (Hash)

    String



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
# File 'lib/privy/public_api/services/wallets.rb', line 316

def export(
  wallet_id,
  export_seed_phrase: nil,
  authorization_context: nil,
  request_expiry: nil,
  request_options: nil
)
  recipient = Privy::Cryptography::HpkeRecipient.new
  export_params = {
    encryption_type: "HPKE",
    recipient_public_key: Base64.strict_encode64(recipient.public_key_spki)
  }
  export_params[:export_seed_phrase] = export_seed_phrase unless export_seed_phrase.nil?

  prepared = Privy::Authorization.prepare_request(
    privy_client,
    method: :post,
    url: Privy::Authorization.signed_url(privy_client, "v1/wallets/#{wallet_id}/export"),
    body: export_params,
    authorization_context: authorization_context,
    request_expiry: privy_client.compute_request_expiry(request_expiry)
  )
  combined_params = export_params.merge(request_options: request_options)
  Privy::Authorization.merge_prepared_headers!(combined_params, prepared.headers)

  response = super(wallet_id, combined_params)
  unless response.encryption_type.to_s == "HPKE"
    raise Privy::Errors::Error, "Invalid encryption type: #{response.encryption_type}"
  end

  private_key = recipient.decrypt(
    Base64.strict_decode64(response.encapsulated_key),
    Base64.strict_decode64(response.ciphertext)
  )

  {private_key: private_key.force_encoding(Encoding::UTF_8)}
end

#export_private_key(wallet_id, authorization_context: nil, request_expiry: nil, request_options: nil) ⇒ Hash

Export a wallet's private key via HPKE.

Returns:

  • (Hash)

    String



357
358
359
360
361
362
363
364
365
# File 'lib/privy/public_api/services/wallets.rb', line 357

def export_private_key(wallet_id, authorization_context: nil, request_expiry: nil, request_options: nil)
  export(
    wallet_id,
    export_seed_phrase: false,
    authorization_context: authorization_context,
    request_expiry: request_expiry,
    request_options: request_options
  )
end

#export_seed_phrase(wallet_id, authorization_context: nil, request_expiry: nil, request_options: nil) ⇒ Hash

Export a wallet's seed phrase via HPKE.

Returns:

  • (Hash)

    String



370
371
372
373
374
375
376
377
378
379
# File 'lib/privy/public_api/services/wallets.rb', line 370

def export_seed_phrase(wallet_id, authorization_context: nil, request_expiry: nil, request_options: nil)
  exported = export(
    wallet_id,
    export_seed_phrase: true,
    authorization_context: authorization_context,
    request_expiry: request_expiry,
    request_options: request_options
  )
  {seed_phrase: exported.fetch(:private_key)}
end

#import(wallet:, additional_signers: nil, display_name: nil, external_id: nil, owner: nil, owner_id: nil, policy_ids: nil, request_options: nil) ⇒ Privy::Models::Wallet

Import an externally generated wallet by encrypting its entropy with HPKE.

Parameters:

  • wallet (Hash)

    Import wallet parameters plus :private_key entropy.

  • request_options (Privy::RequestOptions, Hash, nil) (defaults to: nil)

    Transport-level config (timeouts, retries).

Options Hash (wallet:):

  • :private_key (String)

    Private key or seed phrase entropy to import.

  • :entropy_type (String, Symbol)

    "hd" or "private-key".

  • :chain_type (String, Symbol)

    "ethereum" or "solana".

Returns:

Raises:



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/privy/public_api/services/wallets.rb', line 59

def import(
  wallet:,
  additional_signers: nil,
  display_name: nil,
  external_id: nil,
  owner: nil,
  owner_id: nil,
  policy_ids: nil,
  request_options: nil
)
  import_wallet = wallet.transform_keys { |key| key.respond_to?(:to_sym) ? key.to_sym : key }
  private_key = import_wallet.delete(:private_key)
  raise Privy::Errors::Error, "wallet.private_key is required" if private_key.nil?
  if import_wallet.key?(:hpke_config)
    raise Privy::Errors::Error,
          "wallet.hpke_config is not supported: encryption parameters are fixed by the SDK"
  end

  private_key_bytes = Privy::WalletEntropy.entropy_to_bytes(
    entropy: private_key,
    entropy_type: import_wallet.fetch(:entropy_type),
    chain_type: import_wallet.fetch(:chain_type)
  )

  init_response = _init_import(
    body: import_wallet.merge(encryption_type: "HPKE"),
    request_options: request_options
  )
  unless init_response.encryption_type.to_s == "HPKE"
    raise Privy::Errors::Error, "Invalid encryption type: #{init_response.encryption_type}"
  end

  encrypted = Privy::Cryptography::HpkeSender.new.encrypt(
    Base64.strict_decode64(init_response.encryption_public_key),
    private_key_bytes
  )

  submit_params = {
    wallet: import_wallet.merge(
      encryption_type: "HPKE",
      encapsulated_key: Base64.strict_encode64(encrypted.encapsulated_key),
      ciphertext: Base64.strict_encode64(encrypted.ciphertext)
    ),
    request_options: request_options
  }
  {
    additional_signers: additional_signers,
    display_name: display_name,
    external_id: external_id,
    owner: owner,
    owner_id: owner_id,
    policy_ids: policy_ids
  }.each do |key, value|
    submit_params[key] = value unless value.nil?
  end

  _submit_import(submit_params)
end

#raw_sign(wallet_id, raw_sign_input:, authorization_context: nil, idempotency_key: nil, request_expiry: nil, request_options: nil) ⇒ Privy::Models::RawSignResponse

Sign a hash or raw bytes with a wallet by wallet ID.

Examples:

Sign a pre-computed hash

client.wallets.raw_sign("wallet-id", raw_sign_input: {
  params: {hash: "0x1234...abcdef"}
})

Sign raw bytes with a hash function

client.wallets.raw_sign("wallet-id", raw_sign_input: {
  params: {bytes: "0a0234ea...", encoding: "hex", hash_function: "sha256"}
}, authorization_context: ctx)

Parameters:

  • wallet_id (String)

    ID of the wallet to sign with.

  • raw_sign_input (Hash)

    Body parameters for the raw_sign operation (RawSignInput shape).

  • authorization_context (Privy::Authorization::AuthorizationContext, nil) (defaults to: nil)

    Authorization context for owned wallets.

  • idempotency_key (String, nil) (defaults to: nil)

    Ensures the request is executed only once.

  • request_expiry (Integer, nil) (defaults to: nil)

    Absolute Unix-ms timestamp at which the request expires. Defaults to the value computed by the client's PrivyRequestExpiryOptions.

  • request_options (Privy::RequestOptions, Hash, nil) (defaults to: nil)

    Transport-level config (timeouts, retries).

Options Hash (raw_sign_input:):

  • :params (Hash)

    The signing parameters (required). Either hash: or encoding:, hash_function:.

Returns:



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/privy/public_api/services/wallets.rb', line 233

def raw_sign(
  wallet_id,
  raw_sign_input:,
  authorization_context: nil,
  idempotency_key: nil,
  request_expiry: nil,
  request_options: nil
)
  prepared = Privy::Authorization.prepare_request(
    privy_client,
    method: :post,
    url: Privy::Authorization.signed_url(privy_client, "v1/wallets/#{wallet_id}/raw_sign"),
    body: raw_sign_input,
    authorization_context: authorization_context,
    idempotency_key: idempotency_key,
    request_expiry: privy_client.compute_request_expiry(request_expiry)
  )
  combined_params = raw_sign_input.merge(request_options: request_options)
  Privy::Authorization.merge_prepared_headers!(combined_params, prepared.headers)
  super(wallet_id, combined_params)
end

#rpc(wallet_id, wallet_rpc_request_body:, authorization_context: nil, idempotency_key: nil, request_expiry: nil, request_options: nil) ⇒ Privy::Models::WalletRpcResponse

Sign a message or transaction with a wallet by wallet ID.

Examples:

Personal sign on an ownerless wallet

client.wallets.rpc("wallet-id", wallet_rpc_request_body: {
  method: "personal_sign",
  chain_type: "ethereum",
  params: {message: "hello", encoding: "utf-8"}
})

Sign a transaction with authorization

client.wallets.rpc("wallet-id", wallet_rpc_request_body: {
  method: "eth_signTransaction",
  chain_type: "ethereum",
  params: {transaction: {to: "0x...", value: "0x0", chain_id: 1}}
}, authorization_context: ctx)

Parameters:

  • wallet_id (String)

    ID of the wallet.

  • wallet_rpc_request_body (Hash)

    The RPC request body, discriminated by :method.

  • authorization_context (Privy::Authorization::AuthorizationContext, nil) (defaults to: nil)

    Authorization context for owned wallets.

  • idempotency_key (String, nil) (defaults to: nil)

    Ensures the request is executed only once.

  • request_expiry (Integer, nil) (defaults to: nil)

    Absolute Unix-ms timestamp at which the request expires. Defaults to the value computed by the client's PrivyRequestExpiryOptions.

  • request_options (Privy::RequestOptions, Hash, nil) (defaults to: nil)

    Transport-level config (timeouts, retries).

Options Hash (wallet_rpc_request_body:):

  • :method (String)

    The RPC method name (e.g. "personal_sign", "eth_signTransaction").

  • :chain_type (String)

    The chain type (e.g. "ethereum", "solana").

  • :params (Hash)

    Method-specific parameters.

Returns:



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/privy/public_api/services/wallets.rb', line 188

def rpc(
  wallet_id,
  wallet_rpc_request_body:,
  authorization_context: nil,
  idempotency_key: nil,
  request_expiry: nil,
  request_options: nil
)
  prepared = Privy::Authorization.prepare_request(
    privy_client,
    method: :post,
    url: Privy::Authorization.signed_url(privy_client, "v1/wallets/#{wallet_id}/rpc"),
    body: wallet_rpc_request_body,
    authorization_context: authorization_context,
    idempotency_key: idempotency_key,
    request_expiry: privy_client.compute_request_expiry(request_expiry)
  )
  combined_params = {wallet_rpc_request_body: wallet_rpc_request_body, request_options: request_options}
  Privy::Authorization.merge_prepared_headers!(combined_params, prepared.headers)
  super(wallet_id, combined_params)
end

#transfer(wallet_id, wallet_transfer_params:, authorization_context: nil, idempotency_key: nil, request_expiry: nil, request_options: nil) ⇒ Privy::Models::TransferActionResponse

Transfer tokens from a wallet to a destination address.

Examples:

Transfer USDC on Base

client.wallets.transfer("wallet-id", wallet_transfer_params: {
  source: {asset: "usdc", amount: "10.5", chain: "base"},
  destination: {address: "0xB00F...28a2"}
})

Cross-asset transfer with slippage

client.wallets.transfer("wallet-id", wallet_transfer_params: {
  source: {asset: "usdc", amount: "10.5", chain: "base"},
  destination: {address: "0xB00F...28a2", asset: "usdt", chain: "ethereum"},
  amount_type: "exact_input",
  slippage_bps: 100
}, authorization_context: ctx)

Parameters:

  • wallet_id (String)

    ID of the wallet to transfer from.

  • wallet_transfer_params (Hash)

    Body parameters for the transfer operation.

  • authorization_context (Privy::Authorization::AuthorizationContext, nil) (defaults to: nil)

    Authorization context for owned wallets.

  • idempotency_key (String, nil) (defaults to: nil)

    Ensures the request is executed only once.

  • request_expiry (Integer, nil) (defaults to: nil)

    Absolute Unix-ms timestamp at which the request expires. Defaults to the value computed by the client's PrivyRequestExpiryOptions.

  • request_options (Privy::RequestOptions, Hash, nil) (defaults to: nil)

    Transport-level config (timeouts, retries).

Options Hash (wallet_transfer_params:):

  • :source (Hash)

    Source asset, amount, and chain (required).

  • :destination (Hash)

    Destination address, and optionally asset and chain (required).

  • :amount_type (String)

    Whether amount refers to input or output token ("exact_input" or "exact_output").

  • :slippage_bps (Integer)

    Maximum allowed slippage in basis points (1 bps = 0.01%).

Returns:

  • (Privy::Models::TransferActionResponse)


285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/privy/public_api/services/wallets.rb', line 285

def transfer(
  wallet_id,
  wallet_transfer_params:,
  authorization_context: nil,
  idempotency_key: nil,
  request_expiry: nil,
  request_options: nil
)
  prepared = Privy::Authorization.prepare_request(
    privy_client,
    method: :post,
    url: Privy::Authorization.signed_url(privy_client, "v1/wallets/#{wallet_id}/transfer"),
    body: wallet_transfer_params,
    authorization_context: authorization_context,
    idempotency_key: idempotency_key,
    request_expiry: privy_client.compute_request_expiry(request_expiry)
  )
  combined_params = wallet_transfer_params.merge(request_options: request_options)
  Privy::Authorization.merge_prepared_headers!(combined_params, prepared.headers)
  _transfer(wallet_id, combined_params)
end

#update(wallet_id, wallet_update_params:, authorization_context: nil, request_expiry: nil, request_options: nil) ⇒ Privy::Models::Wallet

Update a wallet's policies or authorization key configuration.

Examples:

Update wallet policies

client.wallets.update("wallet-id", wallet_update_params: {
  policy_ids: ["policy-id"]
}, authorization_context: ctx)

Parameters:

  • wallet_id (String)

    ID of the wallet to update.

  • wallet_update_params (Hash)

    Body parameters for the update.

  • authorization_context (Privy::Authorization::AuthorizationContext, nil) (defaults to: nil)

    Authorization context for owned wallets.

  • request_expiry (Integer, nil) (defaults to: nil)

    Absolute Unix-ms timestamp at which the request expires. Defaults to the value computed by the client's PrivyRequestExpiryOptions.

  • request_options (Privy::RequestOptions, Hash, nil) (defaults to: nil)

    Transport-level config (timeouts, retries).

Options Hash (wallet_update_params:):

  • :owner (Hash, nil)

    New owner specified as user_id: or public_key:.

  • :owner_id (String, nil)

    Key quorum ID to set as owner.

  • :policy_ids (Array<String>, nil)

    New policy IDs to enforce on the wallet.

  • :display_name (String, nil)

    A human-readable label for the wallet. Set to nil to clear.

  • :additional_signers (Array<Hash>, nil)

    Additional signers for the wallet.

Returns:



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/privy/public_api/services/wallets.rb', line 139

def update(
  wallet_id,
  wallet_update_params:,
  authorization_context: nil,
  request_expiry: nil,
  request_options: nil
)
  prepared = Privy::Authorization.prepare_request(
    privy_client,
    method: :patch,
    url: Privy::Authorization.signed_url(privy_client, "v1/wallets/#{wallet_id}"),
    body: wallet_update_params,
    authorization_context: authorization_context,
    request_expiry: privy_client.compute_request_expiry(request_expiry)
  )
  combined_params = wallet_update_params.merge(request_options: request_options)
  Privy::Authorization.merge_prepared_headers!(combined_params, prepared.headers)
  super(wallet_id, combined_params)
end