Struct flow_sdk::account::Account [−][src]
pub struct Account<Client, SecretKey = DefaultSecretKey, Signer = DefaultSigner, Hasher = DefaultHasher> { /* fields omitted */ }
Expand description
An account.
This is your gateway to making transactions, as this holds the secret keys necessary for signing them, as well as the client, for sending any requests over the network.
Implementations
Returns the address of this account.
Returns the signer.
Examples found in repository
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 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
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let stdin = stdin();
let mut stdin = stdin.lock();
let mut buf = String::new();
// Let's make a transaction!
// First, generate a keypair for us to use.
let secp = Secp256k1::signing_only();
// `EntropyRng` is a secure random number generator.
let mut rng = secp256k1::rand::rngs::EntropyRng::new();
let secret_key = SecretKey::new(&mut rng);
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
// Print the public key as a hexadecimal.
println!("This is your public key:");
let public_key_bytes = public_key.serialize_uncompressed();
// There is a leading 0x04 which we don't need to emit
// https://bitcoin.stackexchange.com/a/3043
for ch in &public_key_bytes[1..] {
print!("{:02x}", *ch);
}
println!();
println!("Go to https://flow-faucet.vercel.app/, select secp256k1 and sha3 and create your testnet account.");
println!("Paste the address you get and press ENTER to continue");
stdin.read_line(&mut buf)?;
let addr = buf.trim();
let address: AddressOwned = addr.parse()?;
let net = TonicHyperFlowClient::testnet().await?;
let mut account = Account::<_, _>::new(net, &address.data, secret_key).await?;
let create_account = CreateAccountTransaction {
public_keys: &[public_key],
};
let create_account_header = create_account.to_header::<_, tiny_keccak::Sha3>(account.signer());
let res = account
.send_transaction_header(&create_account_header)
.await?;
println!(
"Just made {} to create another account :p",
hex::encode(&res.id)
);
let response = res.finalize(account.client()).await?;
match response {
Some(res) => {
for ev in res.events.iter() {
if ev.ty == "flow.AccountCreated" {
let payload = ev.parse_payload()?;
let addr = payload
.fields
.into_iter()
.find(|field| field.name == "address")
.map(|field| field.value)
.unwrap();
if let ValueOwned::Address(addr) = addr {
println!("Created account's address is: {}", addr);
}
}
}
}
None => {
panic!("The transaction did not get sealed... Perhaps the network is malfunctioning?")
}
}
Ok(())
}
Returns the client.
Examples found in repository
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 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
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let stdin = stdin();
let mut stdin = stdin.lock();
let mut buf = String::new();
// Let's make a transaction!
// First, generate a keypair for us to use.
let secp = Secp256k1::signing_only();
// `EntropyRng` is a secure random number generator.
let mut rng = secp256k1::rand::rngs::EntropyRng::new();
let secret_key = SecretKey::new(&mut rng);
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
// Print the public key as a hexadecimal.
println!("This is your public key:");
let public_key_bytes = public_key.serialize_uncompressed();
// There is a leading 0x04 which we don't need to emit
// https://bitcoin.stackexchange.com/a/3043
for ch in &public_key_bytes[1..] {
print!("{:02x}", *ch);
}
println!();
println!("Go to https://flow-faucet.vercel.app/, select secp256k1 and sha3 and create your testnet account.");
println!("Paste the address you get and press ENTER to continue");
stdin.read_line(&mut buf)?;
let addr = buf.trim();
let address: AddressOwned = addr.parse()?;
let net = TonicHyperFlowClient::testnet().await?;
let mut account = Account::<_, _>::new(net, &address.data, secret_key).await?;
let create_account = CreateAccountTransaction {
public_keys: &[public_key],
};
let create_account_header = create_account.to_header::<_, tiny_keccak::Sha3>(account.signer());
let res = account
.send_transaction_header(&create_account_header)
.await?;
println!(
"Just made {} to create another account :p",
hex::encode(&res.id)
);
let response = res.finalize(account.client()).await?;
match response {
Some(res) => {
for ev in res.events.iter() {
if ev.ty == "flow.AccountCreated" {
let payload = ev.parse_payload()?;
let addr = payload
.fields
.into_iter()
.find(|field| field.name == "address")
.map(|field| field.value)
.unwrap();
if let ValueOwned::Address(addr) = addr {
println!("Created account's address is: {}", addr);
}
}
}
}
None => {
panic!("The transaction did not get sealed... Perhaps the network is malfunctioning?")
}
}
Ok(())
}
Clones the client from this account.
Returns the primary public key of this account.
Returns the primary key id number of this account.
impl<Client, SecretKey, Signer, Hasher> Account<Client, SecretKey, Signer, Hasher> where
Signer: FlowSigner<SecretKey = SecretKey>,
Hasher: FlowHasher,
impl<Client, SecretKey, Signer, Hasher> Account<Client, SecretKey, Signer, Hasher> where
Signer: FlowSigner<SecretKey = SecretKey>,
Hasher: FlowHasher,
pub async fn new<Addr>(
client: Client,
address: Addr,
secret_key: SecretKey
) -> Result<Self, Error> where
Client: GrpcClient<GetAccountAtLatestBlockRequest<Addr>, AccountResponse>,
pub async fn new<Addr>(
client: Client,
address: Addr,
secret_key: SecretKey
) -> Result<Self, Error> where
Client: GrpcClient<GetAccountAtLatestBlockRequest<Addr>, AccountResponse>,
Logs in to the account with one key, verifying that the key and the address matches.
Errors
This function returns an error if:
- the client returns any errors while making requests
- the secret key does not have the full weight to be able to act on its own (weight < 1000)
- could not find any public key of the account that matches the secret key supplied.
- the algorithms for the signer and the hasher do not match with the public information of the key.
Examples found in repository
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 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
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let stdin = stdin();
let mut stdin = stdin.lock();
let mut buf = String::new();
// Let's make a transaction!
// First, generate a keypair for us to use.
let secp = Secp256k1::signing_only();
// `EntropyRng` is a secure random number generator.
let mut rng = secp256k1::rand::rngs::EntropyRng::new();
let secret_key = SecretKey::new(&mut rng);
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
// Print the public key as a hexadecimal.
println!("This is your public key:");
let public_key_bytes = public_key.serialize_uncompressed();
// There is a leading 0x04 which we don't need to emit
// https://bitcoin.stackexchange.com/a/3043
for ch in &public_key_bytes[1..] {
print!("{:02x}", *ch);
}
println!();
println!("Go to https://flow-faucet.vercel.app/, select secp256k1 and sha3 and create your testnet account.");
println!("Paste the address you get and press ENTER to continue");
stdin.read_line(&mut buf)?;
let addr = buf.trim();
let address: AddressOwned = addr.parse()?;
let net = TonicHyperFlowClient::testnet().await?;
let mut account = Account::<_, _>::new(net, &address.data, secret_key).await?;
let create_account = CreateAccountTransaction {
public_keys: &[public_key],
};
let create_account_header = create_account.to_header::<_, tiny_keccak::Sha3>(account.signer());
let res = account
.send_transaction_header(&create_account_header)
.await?;
println!(
"Just made {} to create another account :p",
hex::encode(&res.id)
);
let response = res.finalize(account.client()).await?;
match response {
Some(res) => {
for ev in res.events.iter() {
if ev.ty == "flow.AccountCreated" {
let payload = ev.parse_payload()?;
let addr = payload
.fields
.into_iter()
.find(|field| field.name == "address")
.map(|field| field.value)
.unwrap();
if let ValueOwned::Address(addr) = addr {
println!("Created account's address is: {}", addr);
}
}
}
}
None => {
panic!("The transaction did not get sealed... Perhaps the network is malfunctioning?")
}
}
Ok(())
}
pub async fn new_multisign<Addr>(
client: Client,
address: Addr,
primary_index: usize,
secret_keys: &[SecretKey]
) -> Result<Self, Error> where
Client: GrpcClient<GetAccountAtLatestBlockRequest<Addr>, AccountResponse>,
SecretKey: Clone,
pub async fn new_multisign<Addr>(
client: Client,
address: Addr,
primary_index: usize,
secret_keys: &[SecretKey]
) -> Result<Self, Error> where
Client: GrpcClient<GetAccountAtLatestBlockRequest<Addr>, AccountResponse>,
SecretKey: Clone,
Logs in to the account with multiple keys, verifying that the keys and the address matches.
Errors
This function returns an error if:
- the client returns any errors while making requests
- the secret keys does not add up to the full weight to be able to sign (weight < 1000)
- could not find any public key of the account that matches one of the the secret key supplied.
- there were duplicate secret keys supplied
- the algorithms for the signer and the hasher do not match with the public information of a key.
pub unsafe fn new_unchecked(
client: Client,
address: Box<[u8]>,
sign_method: SignMethod<SecretKey>
) -> Self
pub unsafe fn new_unchecked(
client: Client,
address: Box<[u8]>,
sign_method: SignMethod<SecretKey>
) -> Self
Creates a new account without checking that the address has the specified key.
Safety
This is unsafe because it can end up signing with a wrong/revoked key, which means transactions sent to the network could fail.
Do not do this unless you are sure that the key(s) contained in the sign method matches the address.
pub async fn primary_key_sequence_number<'a>(
&'a mut self
) -> Result<u32, BoxError> where
Client: GrpcClient<GetAccountAtLatestBlockRequest<&'a [u8]>, AccountResponse>,
pub async fn primary_key_sequence_number<'a>(
&'a mut self
) -> Result<u32, BoxError> where
Client: GrpcClient<GetAccountAtLatestBlockRequest<&'a [u8]>, AccountResponse>,
Queries the sequence number for the primary key from the network.
Creates signature(s) using this account’s public key(s), consuming a populated hasher.
Creates signature(s) using this account’s public key(s), signing provided data.
Signs a party, assuming that you have confirmed all the details of the party.
Signs the party as the payer, thereby converting the party into a transaction, ready to be sent.
Sign a transaction with this account being the proposer, the payer and the only authorizer.
Returns an envelope signature.
pub fn sign_transaction_header<'a, Arguments>(
&self,
header: &'a TransactionHeader<Arguments>,
reference_block_id: impl AsRef<[u8]>,
sequence_number: u64,
gas_limit: u64
) -> SignIter<'_, Signer>ⓘ where
&'a Arguments: IntoIterator,
<&'a Arguments as IntoIterator>::IntoIter: ExactSizeIterator,
<<&'a Arguments as IntoIterator>::IntoIter as Iterator>::Item: AsRef<[u8]>,
pub fn sign_transaction_header<'a, Arguments>(
&self,
header: &'a TransactionHeader<Arguments>,
reference_block_id: impl AsRef<[u8]>,
sequence_number: u64,
gas_limit: u64
) -> SignIter<'_, Signer>ⓘ where
&'a Arguments: IntoIterator,
<&'a Arguments as IntoIterator>::IntoIter: ExactSizeIterator,
<<&'a Arguments as IntoIterator>::IntoIter as Iterator>::Item: AsRef<[u8]>,
Sign a transaction header with a block id and gas limit.
pub async fn send_transaction_header<'a, Arguments, Argument>(
&'a mut self,
transaction: &'a TransactionHeader<Arguments>
) -> Result<SendTransactionResponse, BoxError> where
Client: for<'b> GrpcClient<GetAccountAtLatestBlockRequest<&'b [u8]>, AccountResponse>,
Client: GrpcClient<GetLatestBlockHeaderRequest, BlockHeaderResponse>,
for<'b> Client: GrpcClient<SendTransactionRequest<&'b [u8], &'b SliceHelper<Argument>, &'b [u8], &'b [u8], &'b [u8], [&'b [u8]; 1], [SignatureE<&'b [u8], &'b [u8]>; 0], EmitRefAndDropOnNext<SignatureE<&'b [u8], <Signer::Signature as Signature>::Serialized>, MkSigIter<'b, KeyIdIter<'b, Signer::SecretKey>, SignIter<'b, Signer>>>>, SendTransactionResponse>,
Arguments: AsRef<[Argument]>,
Argument: AsRef<[u8]>,
&'a Arguments: IntoIterator,
<&'a Arguments as IntoIterator>::IntoIter: ExactSizeIterator,
<<&'a Arguments as IntoIterator>::IntoIter as Iterator>::Item: AsRef<[u8]>,
pub async fn send_transaction_header<'a, Arguments, Argument>(
&'a mut self,
transaction: &'a TransactionHeader<Arguments>
) -> Result<SendTransactionResponse, BoxError> where
Client: for<'b> GrpcClient<GetAccountAtLatestBlockRequest<&'b [u8]>, AccountResponse>,
Client: GrpcClient<GetLatestBlockHeaderRequest, BlockHeaderResponse>,
for<'b> Client: GrpcClient<SendTransactionRequest<&'b [u8], &'b SliceHelper<Argument>, &'b [u8], &'b [u8], &'b [u8], [&'b [u8]; 1], [SignatureE<&'b [u8], &'b [u8]>; 0], EmitRefAndDropOnNext<SignatureE<&'b [u8], <Signer::Signature as Signature>::Serialized>, MkSigIter<'b, KeyIdIter<'b, Signer::SecretKey>, SignIter<'b, Signer>>>>, SendTransactionResponse>,
Arguments: AsRef<[Argument]>,
Argument: AsRef<[u8]>,
&'a Arguments: IntoIterator,
<&'a Arguments as IntoIterator>::IntoIter: ExactSizeIterator,
<<&'a Arguments as IntoIterator>::IntoIter as Iterator>::Item: AsRef<[u8]>,
Send a transaction to the network. Signs the transaction header with a gas limit of 1000 and using the latest sealed block as a reference.
Note that this does not increment the sequence number.
Errors
This function returns an error if the client returns any errors when making requests.
Examples found in repository
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 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
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let stdin = stdin();
let mut stdin = stdin.lock();
let mut buf = String::new();
// Let's make a transaction!
// First, generate a keypair for us to use.
let secp = Secp256k1::signing_only();
// `EntropyRng` is a secure random number generator.
let mut rng = secp256k1::rand::rngs::EntropyRng::new();
let secret_key = SecretKey::new(&mut rng);
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
// Print the public key as a hexadecimal.
println!("This is your public key:");
let public_key_bytes = public_key.serialize_uncompressed();
// There is a leading 0x04 which we don't need to emit
// https://bitcoin.stackexchange.com/a/3043
for ch in &public_key_bytes[1..] {
print!("{:02x}", *ch);
}
println!();
println!("Go to https://flow-faucet.vercel.app/, select secp256k1 and sha3 and create your testnet account.");
println!("Paste the address you get and press ENTER to continue");
stdin.read_line(&mut buf)?;
let addr = buf.trim();
let address: AddressOwned = addr.parse()?;
let net = TonicHyperFlowClient::testnet().await?;
let mut account = Account::<_, _>::new(net, &address.data, secret_key).await?;
let create_account = CreateAccountTransaction {
public_keys: &[public_key],
};
let create_account_header = create_account.to_header::<_, tiny_keccak::Sha3>(account.signer());
let res = account
.send_transaction_header(&create_account_header)
.await?;
println!(
"Just made {} to create another account :p",
hex::encode(&res.id)
);
let response = res.finalize(account.client()).await?;
match response {
Some(res) => {
for ev in res.events.iter() {
if ev.ty == "flow.AccountCreated" {
let payload = ev.parse_payload()?;
let addr = payload
.fields
.into_iter()
.find(|field| field.name == "address")
.map(|field| field.value)
.unwrap();
if let ValueOwned::Address(addr) = addr {
println!("Created account's address is: {}", addr);
}
}
}
}
None => {
panic!("The transaction did not get sealed... Perhaps the network is malfunctioning?")
}
}
Ok(())
}
Trait Implementations
Auto Trait Implementations
impl<Client, SecretKey, Signer, Hasher> RefUnwindSafe for Account<Client, SecretKey, Signer, Hasher> where
Client: RefUnwindSafe,
Hasher: RefUnwindSafe,
SecretKey: RefUnwindSafe,
Signer: RefUnwindSafe,
impl<Client, SecretKey, Signer, Hasher> Send for Account<Client, SecretKey, Signer, Hasher> where
Client: Send,
Hasher: Send,
SecretKey: Send,
Signer: Send,
impl<Client, SecretKey, Signer, Hasher> Sync for Account<Client, SecretKey, Signer, Hasher> where
Client: Sync,
Hasher: Sync,
SecretKey: Sync,
Signer: Sync,
impl<Client, SecretKey, Signer, Hasher> Unpin for Account<Client, SecretKey, Signer, Hasher> where
Client: Unpin,
Hasher: Unpin,
SecretKey: Unpin,
Signer: Unpin,
impl<Client, SecretKey, Signer, Hasher> UnwindSafe for Account<Client, SecretKey, Signer, Hasher> where
Client: UnwindSafe,
Hasher: UnwindSafe,
SecretKey: UnwindSafe,
Signer: UnwindSafe,
Blanket Implementations
Mutably borrows from an owned value. Read more
Wrap the input message T
in a tonic::Request
Attaches the provided Subscriber
to this type, returning a
WithDispatch
wrapper. Read more
Attaches the current default Subscriber
to this type, returning a
WithDispatch
wrapper. Read more