mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-05-15 14:19:27 +00:00
Merge branch 'Pravdyvy/indexer-state-management' into Pravdyvy/bedrock-parsing-from-start-of-a-channel
This commit is contained in:
commit
99a4e8482c
11
.deny.toml
11
.deny.toml
@ -12,6 +12,7 @@ ignore = [
|
|||||||
{ id = "RUSTSEC-2024-0436", reason = "`paste` has a security vulnerability; consider using an alternative. Use `cargo tree -p paste -i > tmp.txt` to check the dependency tree." },
|
{ id = "RUSTSEC-2024-0436", reason = "`paste` has a security vulnerability; consider using an alternative. Use `cargo tree -p paste -i > tmp.txt` to check the dependency tree." },
|
||||||
{ id = "RUSTSEC-2025-0055", reason = "`tracing-subscriber` v0.2.25 pulled in by ark-relations v0.4.0 - will be addressed before mainnet" },
|
{ id = "RUSTSEC-2025-0055", reason = "`tracing-subscriber` v0.2.25 pulled in by ark-relations v0.4.0 - will be addressed before mainnet" },
|
||||||
{ id = "RUSTSEC-2025-0141", reason = "`bincode` is unmaintained but continuing to use it." },
|
{ id = "RUSTSEC-2025-0141", reason = "`bincode` is unmaintained but continuing to use it." },
|
||||||
|
{ id = "RUSTSEC-2023-0089", reason = "atomic-polyfill is pulled transitively via risc0-zkvm; waiting on upstream fix (see https://github.com/risc0/risc0/issues/3453)" },
|
||||||
]
|
]
|
||||||
yanked = "deny"
|
yanked = "deny"
|
||||||
unused-ignored-advisory = "deny"
|
unused-ignored-advisory = "deny"
|
||||||
@ -35,6 +36,16 @@ allow = [
|
|||||||
"Unicode-3.0",
|
"Unicode-3.0",
|
||||||
"Zlib",
|
"Zlib",
|
||||||
]
|
]
|
||||||
|
exceptions = [
|
||||||
|
# TEMP: Pending legal review. Pulled transitively via `risc0-zkvm`
|
||||||
|
{ name = "downloader", version = "0.2.8", allow = ["LGPL-3.0-or-later"] },
|
||||||
|
{ name = "malachite", version = "0.4.22", allow = ["LGPL-3.0-only"] },
|
||||||
|
{ name = "malachite-base", version = "0.4.22", allow = ["LGPL-3.0-only"] },
|
||||||
|
{ name = "malachite-float", version = "0.4.22", allow = ["LGPL-3.0-only"] },
|
||||||
|
{ name = "malachite-nz", version = "0.4.22", allow = ["LGPL-3.0-only"] },
|
||||||
|
{ name = "malachite-q", version = "0.4.22", allow = ["LGPL-3.0-only"] },
|
||||||
|
{ name = "managed", version = "0.8.0", allow = ["0BSD"] },
|
||||||
|
]
|
||||||
private = { ignore = false }
|
private = { ignore = false }
|
||||||
unused-allowed-license = "deny"
|
unused-allowed-license = "deny"
|
||||||
|
|
||||||
|
|||||||
1428
Cargo.lock
generated
1428
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -67,8 +67,8 @@ tokio = { version = "1.28.2", features = [
|
|||||||
"fs",
|
"fs",
|
||||||
] }
|
] }
|
||||||
tokio-util = "0.7.18"
|
tokio-util = "0.7.18"
|
||||||
risc0-zkvm = { version = "3.0.3", features = ['std'] }
|
risc0-zkvm = { version = "3.0.5", features = ['std'] }
|
||||||
risc0-build = "3.0.3"
|
risc0-build = "3.0.5"
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
num_cpus = "1.13.1"
|
num_cpus = "1.13.1"
|
||||||
openssl = { version = "0.10", features = ["vendored"] }
|
openssl = { version = "0.10", features = ["vendored"] }
|
||||||
|
|||||||
@ -92,7 +92,7 @@ wallet account new private
|
|||||||
# Output:
|
# Output:
|
||||||
Generated new account with account_id Private/HMRHZdPw4pbyPVZHNGrV6K5AA95wACFsHTRST84fr3CF
|
Generated new account with account_id Private/HMRHZdPw4pbyPVZHNGrV6K5AA95wACFsHTRST84fr3CF
|
||||||
With npk 6a2dfe433cf28e525aa0196d719be3c16146f7ee358ca39595323f94fde38f93
|
With npk 6a2dfe433cf28e525aa0196d719be3c16146f7ee358ca39595323f94fde38f93
|
||||||
With ipk 03d59abf4bee974cc12ddb44641c19f0b5441fef39191f047c988c29a77252a577
|
With vpk 03d59abf4bee974cc12ddb44641c19f0b5441fef39191f047c988c29a77252a577
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Create the token (Token B):
|
2. Create the token (Token B):
|
||||||
|
|||||||
@ -154,11 +154,11 @@ wallet account new private
|
|||||||
# Output:
|
# Output:
|
||||||
Generated new account with account_id Private/HacPU3hakLYzWtSqUPw6TUr8fqoMieVWovsUR6sJf7cL
|
Generated new account with account_id Private/HacPU3hakLYzWtSqUPw6TUr8fqoMieVWovsUR6sJf7cL
|
||||||
With npk e6366f79d026c8bd64ae6b3d601f0506832ec682ab54897f205fffe64ec0d951
|
With npk e6366f79d026c8bd64ae6b3d601f0506832ec682ab54897f205fffe64ec0d951
|
||||||
With ipk 02ddc96d0eb56e00ce14994cfdaec5ae1f76244180a919545983156e3519940a17
|
With vpk 02ddc96d0eb56e00ce14994cfdaec5ae1f76244180a919545983156e3519940a17
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!Tip]
|
> [!Tip]
|
||||||
> Focus on the account ID for now. The `npk` and `ipk` values are stored locally and used to build privacy-preserving transactions. The private account ID is derived from `npk`.
|
> Focus on the account ID for now. The `npk` and `vpk` values are stored locally and used to build privacy-preserving transactions. The private account ID is derived from `npk`.
|
||||||
|
|
||||||
Just like public accounts, new private accounts start out uninitialized:
|
Just like public accounts, new private accounts start out uninitialized:
|
||||||
|
|
||||||
@ -228,17 +228,17 @@ wallet account new private
|
|||||||
# Output:
|
# Output:
|
||||||
Generated new account with account_id Private/AukXPRBmrYVqoqEW2HTs7N3hvTn3qdNFDcxDHVr5hMm5
|
Generated new account with account_id Private/AukXPRBmrYVqoqEW2HTs7N3hvTn3qdNFDcxDHVr5hMm5
|
||||||
With npk 0c95ebc4b3830f53da77bb0b80a276a776cdcf6410932acc718dcdb3f788a00e
|
With npk 0c95ebc4b3830f53da77bb0b80a276a776cdcf6410932acc718dcdb3f788a00e
|
||||||
With ipk 039fd12a3674a880d3e917804129141e4170d419d1f9e28a3dcf979c1f2369cb72
|
With vpk 039fd12a3674a880d3e917804129141e4170d419d1f9e28a3dcf979c1f2369cb72
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!Tip]
|
> [!Tip]
|
||||||
> Ignore the private account ID here and use the `npk` and `ipk` values to send to a foreign private account.
|
> Ignore the private account ID here and use the `npk` and `vpk` values to send to a foreign private account.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wallet auth-transfer send \
|
wallet auth-transfer send \
|
||||||
--from Public/Ev1JprP9BmhbFVQyBcbznU8bAXcwrzwRoPTetXdQPAWS \
|
--from Public/Ev1JprP9BmhbFVQyBcbznU8bAXcwrzwRoPTetXdQPAWS \
|
||||||
--to-npk 0c95ebc4b3830f53da77bb0b80a276a776cdcf6410932acc718dcdb3f788a00e \
|
--to-npk 0c95ebc4b3830f53da77bb0b80a276a776cdcf6410932acc718dcdb3f788a00e \
|
||||||
--to-ipk 039fd12a3674a880d3e917804129141e4170d419d1f9e28a3dcf979c1f2369cb72 \
|
--to-vpk 039fd12a3674a880d3e917804129141e4170d419d1f9e28a3dcf979c1f2369cb72 \
|
||||||
--amount 3
|
--amount 3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -97,7 +97,7 @@ _wallet_auth_transfer() {
|
|||||||
'--from[Source account ID]:from_account:_wallet_account_ids' \
|
'--from[Source account ID]:from_account:_wallet_account_ids' \
|
||||||
'--to[Destination account ID (for owned accounts)]:to_account:_wallet_account_ids' \
|
'--to[Destination account ID (for owned accounts)]:to_account:_wallet_account_ids' \
|
||||||
'--to-npk[Destination nullifier public key (for foreign private accounts)]:npk:' \
|
'--to-npk[Destination nullifier public key (for foreign private accounts)]:npk:' \
|
||||||
'--to-ipk[Destination viewing public key (for foreign private accounts)]:ipk:' \
|
'--to-vpk[Destination viewing public key (for foreign private accounts)]:vpk:' \
|
||||||
'--amount[Amount of native tokens to send]:amount:'
|
'--amount[Amount of native tokens to send]:amount:'
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -164,7 +164,7 @@ _wallet_account() {
|
|||||||
get)
|
get)
|
||||||
_arguments \
|
_arguments \
|
||||||
'(-r --raw)'{-r,--raw}'[Get raw account data]' \
|
'(-r --raw)'{-r,--raw}'[Get raw account data]' \
|
||||||
'(-k --keys)'{-k,--keys}'[Display keys (pk for public accounts, npk/ipk for private accounts)]' \
|
'(-k --keys)'{-k,--keys}'[Display keys (pk for public accounts, npk/vpk for private accounts)]' \
|
||||||
'(-a --account-id)'{-a,--account-id}'[Account ID to query]:account_id:_wallet_account_ids'
|
'(-a --account-id)'{-a,--account-id}'[Account ID to query]:account_id:_wallet_account_ids'
|
||||||
;;
|
;;
|
||||||
list|ls)
|
list|ls)
|
||||||
@ -255,7 +255,7 @@ _wallet_token() {
|
|||||||
'--from[Source holding account ID]:from_account:_wallet_account_ids' \
|
'--from[Source holding account ID]:from_account:_wallet_account_ids' \
|
||||||
'--to[Destination holding account ID (for owned accounts)]:to_account:_wallet_account_ids' \
|
'--to[Destination holding account ID (for owned accounts)]:to_account:_wallet_account_ids' \
|
||||||
'--to-npk[Destination nullifier public key (for foreign private accounts)]:npk:' \
|
'--to-npk[Destination nullifier public key (for foreign private accounts)]:npk:' \
|
||||||
'--to-ipk[Destination viewing public key (for foreign private accounts)]:ipk:' \
|
'--to-vpk[Destination viewing public key (for foreign private accounts)]:vpk:' \
|
||||||
'--amount[Amount of tokens to send]:amount:'
|
'--amount[Amount of tokens to send]:amount:'
|
||||||
;;
|
;;
|
||||||
burn)
|
burn)
|
||||||
@ -269,7 +269,7 @@ _wallet_token() {
|
|||||||
'--definition[Definition account ID]:definition_account:_wallet_account_ids' \
|
'--definition[Definition account ID]:definition_account:_wallet_account_ids' \
|
||||||
'--holder[Holder account ID (for owned accounts)]:holder_account:_wallet_account_ids' \
|
'--holder[Holder account ID (for owned accounts)]:holder_account:_wallet_account_ids' \
|
||||||
'--holder-npk[Holder nullifier public key (for foreign private accounts)]:npk:' \
|
'--holder-npk[Holder nullifier public key (for foreign private accounts)]:npk:' \
|
||||||
'--holder-ipk[Holder viewing public key (for foreign private accounts)]:ipk:' \
|
'--holder-vpk[Holder viewing public key (for foreign private accounts)]:vpk:' \
|
||||||
'--amount[Amount of tokens to mint]:amount:'
|
'--amount[Amount of tokens to mint]:amount:'
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@ -29,40 +29,7 @@
|
|||||||
],
|
],
|
||||||
"initial_commitments": [
|
"initial_commitments": [
|
||||||
{
|
{
|
||||||
"npk": [
|
"npk": [13, 25, 40, 5, 198, 248, 210, 248, 237, 121, 124, 145, 186, 142, 253, 216, 236, 69, 193, 32, 166, 167, 49, 133, 172, 111, 159, 46, 84, 17, 157, 23],
|
||||||
63,
|
|
||||||
202,
|
|
||||||
178,
|
|
||||||
231,
|
|
||||||
183,
|
|
||||||
82,
|
|
||||||
237,
|
|
||||||
212,
|
|
||||||
216,
|
|
||||||
221,
|
|
||||||
215,
|
|
||||||
255,
|
|
||||||
153,
|
|
||||||
101,
|
|
||||||
177,
|
|
||||||
161,
|
|
||||||
254,
|
|
||||||
210,
|
|
||||||
128,
|
|
||||||
122,
|
|
||||||
54,
|
|
||||||
190,
|
|
||||||
230,
|
|
||||||
151,
|
|
||||||
183,
|
|
||||||
64,
|
|
||||||
225,
|
|
||||||
229,
|
|
||||||
113,
|
|
||||||
1,
|
|
||||||
228,
|
|
||||||
97
|
|
||||||
],
|
|
||||||
"account": {
|
"account": {
|
||||||
"program_owner": [
|
"program_owner": [
|
||||||
0,
|
0,
|
||||||
@ -80,40 +47,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npk": [
|
"npk": [32, 67, 72, 164, 106, 53, 66, 239, 141, 15, 52, 230, 136, 177, 2, 236, 207, 243, 134, 135, 210, 143, 87, 232, 215, 128, 194, 120, 113, 224, 4, 165],
|
||||||
192,
|
|
||||||
251,
|
|
||||||
166,
|
|
||||||
243,
|
|
||||||
167,
|
|
||||||
236,
|
|
||||||
84,
|
|
||||||
249,
|
|
||||||
35,
|
|
||||||
136,
|
|
||||||
130,
|
|
||||||
172,
|
|
||||||
219,
|
|
||||||
225,
|
|
||||||
161,
|
|
||||||
139,
|
|
||||||
229,
|
|
||||||
89,
|
|
||||||
243,
|
|
||||||
125,
|
|
||||||
194,
|
|
||||||
213,
|
|
||||||
209,
|
|
||||||
30,
|
|
||||||
23,
|
|
||||||
174,
|
|
||||||
100,
|
|
||||||
244,
|
|
||||||
124,
|
|
||||||
74,
|
|
||||||
140,
|
|
||||||
47
|
|
||||||
],
|
|
||||||
"account": {
|
"account": {
|
||||||
"program_owner": [
|
"program_owner": [
|
||||||
0,
|
0,
|
||||||
|
|||||||
@ -263,7 +263,7 @@ impl indexer_service_rpc::RpcServer for MockIndexerService {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Sort by block ID descending (most recent first)
|
// Sort by block ID descending (most recent first)
|
||||||
account_txs.sort_by(|a, b| b.1.cmp(&a.1));
|
account_txs.sort_by_key(|b| std::cmp::Reverse(b.1));
|
||||||
|
|
||||||
let start = offset as usize;
|
let start = offset as usize;
|
||||||
if start >= account_txs.len() {
|
if start >= account_txs.len() {
|
||||||
|
|||||||
@ -102,7 +102,7 @@ async fn amm_public() -> Result<()> {
|
|||||||
from: format_public_account_id(supply_account_id_1),
|
from: format_public_account_id(supply_account_id_1),
|
||||||
to: Some(format_public_account_id(recipient_account_id_1)),
|
to: Some(format_public_account_id(recipient_account_id_1)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 7,
|
amount: 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ async fn amm_public() -> Result<()> {
|
|||||||
from: format_public_account_id(supply_account_id_2),
|
from: format_public_account_id(supply_account_id_2),
|
||||||
to: Some(format_public_account_id(recipient_account_id_2)),
|
to: Some(format_public_account_id(recipient_account_id_2)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 7,
|
amount: 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ async fn private_transfer_to_owned_account() -> Result<()> {
|
|||||||
from: format_private_account_id(from),
|
from: format_private_account_id(from),
|
||||||
to: Some(format_private_account_id(to)),
|
to: Some(format_private_account_id(to)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -59,13 +59,13 @@ async fn private_transfer_to_foreign_account() -> Result<()> {
|
|||||||
let from: AccountId = ctx.existing_private_accounts()[0];
|
let from: AccountId = ctx.existing_private_accounts()[0];
|
||||||
let to_npk = NullifierPublicKey([42; 32]);
|
let to_npk = NullifierPublicKey([42; 32]);
|
||||||
let to_npk_string = hex::encode(to_npk.0);
|
let to_npk_string = hex::encode(to_npk.0);
|
||||||
let to_ipk = Secp256k1Point::from_scalar(to_npk.0);
|
let to_vpk = Secp256k1Point::from_scalar(to_npk.0);
|
||||||
|
|
||||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||||
from: format_private_account_id(from),
|
from: format_private_account_id(from),
|
||||||
to: None,
|
to: None,
|
||||||
to_npk: Some(to_npk_string),
|
to_npk: Some(to_npk_string),
|
||||||
to_ipk: Some(hex::encode(to_ipk.0)),
|
to_vpk: Some(hex::encode(to_vpk.0)),
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ async fn deshielded_transfer_to_public_account() -> Result<()> {
|
|||||||
from: format_private_account_id(from),
|
from: format_private_account_id(from),
|
||||||
to: Some(format_public_account_id(to)),
|
to: Some(format_public_account_id(to)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -168,12 +168,12 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.context("Failed to get private account")?;
|
.context("Failed to get private account")?;
|
||||||
|
|
||||||
// Send to this account using claiming path (using npk and ipk instead of account ID)
|
// Send to this account using claiming path (using npk and vpk instead of account ID)
|
||||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||||
from: format_private_account_id(from),
|
from: format_private_account_id(from),
|
||||||
to: None,
|
to: None,
|
||||||
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)),
|
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)),
|
||||||
to_ipk: Some(hex::encode(to_keys.incoming_viewing_public_key.0)),
|
to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)),
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ async fn shielded_transfer_to_owned_private_account() -> Result<()> {
|
|||||||
from: format_public_account_id(from),
|
from: format_public_account_id(from),
|
||||||
to: Some(format_private_account_id(to)),
|
to: Some(format_private_account_id(to)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -256,14 +256,14 @@ async fn shielded_transfer_to_foreign_account() -> Result<()> {
|
|||||||
|
|
||||||
let to_npk = NullifierPublicKey([42; 32]);
|
let to_npk = NullifierPublicKey([42; 32]);
|
||||||
let to_npk_string = hex::encode(to_npk.0);
|
let to_npk_string = hex::encode(to_npk.0);
|
||||||
let to_ipk = Secp256k1Point::from_scalar(to_npk.0);
|
let to_vpk = Secp256k1Point::from_scalar(to_npk.0);
|
||||||
let from: AccountId = ctx.existing_public_accounts()[0];
|
let from: AccountId = ctx.existing_public_accounts()[0];
|
||||||
|
|
||||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||||
from: format_public_account_id(from),
|
from: format_public_account_id(from),
|
||||||
to: None,
|
to: None,
|
||||||
to_npk: Some(to_npk_string),
|
to_npk: Some(to_npk_string),
|
||||||
to_ipk: Some(hex::encode(to_ipk.0)),
|
to_vpk: Some(hex::encode(to_vpk.0)),
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -325,12 +325,12 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.context("Failed to get private account")?;
|
.context("Failed to get private account")?;
|
||||||
|
|
||||||
// Send transfer using nullifier and incoming viewing public keys
|
// Send transfer using nullifier and viewing public keys
|
||||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||||
from: format_private_account_id(from),
|
from: format_private_account_id(from),
|
||||||
to: None,
|
to: None,
|
||||||
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)),
|
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)),
|
||||||
to_ipk: Some(hex::encode(to_keys.incoming_viewing_public_key.0)),
|
to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)),
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ async fn successful_transfer_to_existing_account() -> Result<()> {
|
|||||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ pub async fn successful_transfer_to_new_account() -> Result<()> {
|
|||||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||||
to: Some(format_public_account_id(new_persistent_account_id)),
|
to: Some(format_public_account_id(new_persistent_account_id)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ async fn failed_transfer_with_insufficient_balance() -> Result<()> {
|
|||||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 1000000,
|
amount: 1000000,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ async fn two_consecutive_successful_transfers() -> Result<()> {
|
|||||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ async fn two_consecutive_successful_transfers() -> Result<()> {
|
|||||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -12,14 +12,14 @@ use tokio::test;
|
|||||||
use wallet::cli::{Command, programs::native_token_transfer::AuthTransferSubcommand};
|
use wallet::cli::{Command, programs::native_token_transfer::AuthTransferSubcommand};
|
||||||
|
|
||||||
/// Timeout in milliseconds to reliably await for block finalization
|
/// Timeout in milliseconds to reliably await for block finalization
|
||||||
const L2_TO_L1_TIMEOUT_MILLIS: u64 = 120000;
|
const L2_TO_L1_TIMEOUT_MILLIS: u64 = 300000;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "Not reliable with current bedrock node"]
|
||||||
async fn indexer_test_run() -> Result<()> {
|
async fn indexer_test_run() -> Result<()> {
|
||||||
let ctx = TestContext::new().await?;
|
let ctx = TestContext::new().await?;
|
||||||
|
|
||||||
// RUN OBSERVATION
|
// RUN OBSERVATION
|
||||||
info!("LETS TAKE A LOOK");
|
|
||||||
tokio::time::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS)).await;
|
tokio::time::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS)).await;
|
||||||
|
|
||||||
let last_block_seq = ctx
|
let last_block_seq = ctx
|
||||||
@ -45,6 +45,7 @@ async fn indexer_test_run() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "Not reliable with current bedrock node"]
|
||||||
async fn indexer_block_batching() -> Result<()> {
|
async fn indexer_block_batching() -> Result<()> {
|
||||||
let ctx = TestContext::new().await?;
|
let ctx = TestContext::new().await?;
|
||||||
|
|
||||||
@ -80,6 +81,7 @@ async fn indexer_block_batching() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "Not reliable with current bedrock node"]
|
||||||
async fn indexer_state_consistency() -> Result<()> {
|
async fn indexer_state_consistency() -> Result<()> {
|
||||||
let mut ctx = TestContext::new().await?;
|
let mut ctx = TestContext::new().await?;
|
||||||
|
|
||||||
@ -87,7 +89,7 @@ async fn indexer_state_consistency() -> Result<()> {
|
|||||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -119,7 +121,7 @@ async fn indexer_state_consistency() -> Result<()> {
|
|||||||
from: format_private_account_id(from),
|
from: format_private_account_id(from),
|
||||||
to: Some(format_private_account_id(to)),
|
to: Some(format_private_account_id(to)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
|||||||
from: format_private_account_id(from),
|
from: format_private_account_id(from),
|
||||||
to: Some(format_private_account_id(to_account_id1)),
|
to: Some(format_private_account_id(to_account_id1)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 100,
|
amount: 100,
|
||||||
});
|
});
|
||||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||||
@ -60,7 +60,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
|||||||
from: format_private_account_id(from),
|
from: format_private_account_id(from),
|
||||||
to: Some(format_private_account_id(to_account_id2)),
|
to: Some(format_private_account_id(to_account_id2)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 101,
|
amount: 101,
|
||||||
});
|
});
|
||||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||||
@ -96,7 +96,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
|||||||
from: format_public_account_id(from),
|
from: format_public_account_id(from),
|
||||||
to: Some(format_public_account_id(to_account_id3)),
|
to: Some(format_public_account_id(to_account_id3)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 102,
|
amount: 102,
|
||||||
});
|
});
|
||||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||||
@ -106,7 +106,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
|||||||
from: format_public_account_id(from),
|
from: format_public_account_id(from),
|
||||||
to: Some(format_public_account_id(to_account_id4)),
|
to: Some(format_public_account_id(to_account_id4)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 103,
|
amount: 103,
|
||||||
});
|
});
|
||||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||||
@ -169,7 +169,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
|||||||
from: format_private_account_id(to_account_id1),
|
from: format_private_account_id(to_account_id1),
|
||||||
to: Some(format_private_account_id(to_account_id2)),
|
to: Some(format_private_account_id(to_account_id2)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 10,
|
amount: 10,
|
||||||
});
|
});
|
||||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||||
@ -178,7 +178,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
|||||||
from: format_public_account_id(to_account_id3),
|
from: format_public_account_id(to_account_id3),
|
||||||
to: Some(format_public_account_id(to_account_id4)),
|
to: Some(format_public_account_id(to_account_id4)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: 11,
|
amount: 11,
|
||||||
});
|
});
|
||||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||||
|
|||||||
@ -115,7 +115,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
|||||||
from: format_public_account_id(supply_account_id),
|
from: format_public_account_id(supply_account_id),
|
||||||
to: Some(format_public_account_id(recipient_account_id)),
|
to: Some(format_public_account_id(recipient_account_id)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: transfer_amount,
|
amount: transfer_amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
|||||||
definition: format_public_account_id(definition_account_id),
|
definition: format_public_account_id(definition_account_id),
|
||||||
holder: Some(format_public_account_id(recipient_account_id)),
|
holder: Some(format_public_account_id(recipient_account_id)),
|
||||||
holder_npk: None,
|
holder_npk: None,
|
||||||
holder_ipk: None,
|
holder_vpk: None,
|
||||||
amount: mint_amount,
|
amount: mint_amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -343,7 +343,7 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
|
|||||||
from: format_private_account_id(supply_account_id),
|
from: format_private_account_id(supply_account_id),
|
||||||
to: Some(format_private_account_id(recipient_account_id)),
|
to: Some(format_private_account_id(recipient_account_id)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: transfer_amount,
|
amount: transfer_amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -525,7 +525,7 @@ async fn create_token_with_private_definition() -> Result<()> {
|
|||||||
definition: format_private_account_id(definition_account_id),
|
definition: format_private_account_id(definition_account_id),
|
||||||
holder: Some(format_public_account_id(recipient_account_id_public)),
|
holder: Some(format_public_account_id(recipient_account_id_public)),
|
||||||
holder_npk: None,
|
holder_npk: None,
|
||||||
holder_ipk: None,
|
holder_vpk: None,
|
||||||
amount: mint_amount_public,
|
amount: mint_amount_public,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -572,7 +572,7 @@ async fn create_token_with_private_definition() -> Result<()> {
|
|||||||
definition: format_private_account_id(definition_account_id),
|
definition: format_private_account_id(definition_account_id),
|
||||||
holder: Some(format_private_account_id(recipient_account_id_private)),
|
holder: Some(format_private_account_id(recipient_account_id_private)),
|
||||||
holder_npk: None,
|
holder_npk: None,
|
||||||
holder_ipk: None,
|
holder_vpk: None,
|
||||||
amount: mint_amount_private,
|
amount: mint_amount_private,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -701,7 +701,7 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
|
|||||||
from: format_private_account_id(supply_account_id),
|
from: format_private_account_id(supply_account_id),
|
||||||
to: Some(format_private_account_id(recipient_account_id)),
|
to: Some(format_private_account_id(recipient_account_id)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: transfer_amount,
|
amount: transfer_amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -819,7 +819,7 @@ async fn shielded_token_transfer() -> Result<()> {
|
|||||||
from: format_public_account_id(supply_account_id),
|
from: format_public_account_id(supply_account_id),
|
||||||
to: Some(format_private_account_id(recipient_account_id)),
|
to: Some(format_private_account_id(recipient_account_id)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: transfer_amount,
|
amount: transfer_amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -933,7 +933,7 @@ async fn deshielded_token_transfer() -> Result<()> {
|
|||||||
from: format_private_account_id(supply_account_id),
|
from: format_private_account_id(supply_account_id),
|
||||||
to: Some(format_public_account_id(recipient_account_id)),
|
to: Some(format_public_account_id(recipient_account_id)),
|
||||||
to_npk: None,
|
to_npk: None,
|
||||||
to_ipk: None,
|
to_vpk: None,
|
||||||
amount: transfer_amount,
|
amount: transfer_amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1056,7 +1056,7 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
|
|||||||
definition: format_private_account_id(definition_account_id),
|
definition: format_private_account_id(definition_account_id),
|
||||||
holder: None,
|
holder: None,
|
||||||
holder_npk: Some(hex::encode(holder_keys.nullifer_public_key.0)),
|
holder_npk: Some(hex::encode(holder_keys.nullifer_public_key.0)),
|
||||||
holder_ipk: Some(hex::encode(holder_keys.incoming_viewing_public_key.0)),
|
holder_vpk: Some(hex::encode(holder_keys.viewing_public_key.0)),
|
||||||
amount: mint_amount,
|
amount: mint_amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ use nssa::{
|
|||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
MembershipProof, NullifierPublicKey,
|
MembershipProof, NullifierPublicKey,
|
||||||
account::{AccountWithMetadata, data::Data},
|
account::{AccountWithMetadata, data::Data},
|
||||||
encryption::IncomingViewingPublicKey,
|
encryption::ViewingPublicKey,
|
||||||
};
|
};
|
||||||
use tokio::test;
|
use tokio::test;
|
||||||
|
|
||||||
@ -192,8 +192,8 @@ impl TpsTestManager {
|
|||||||
fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
||||||
let program = Program::authenticated_transfer_program();
|
let program = Program::authenticated_transfer_program();
|
||||||
let sender_nsk = [1; 32];
|
let sender_nsk = [1; 32];
|
||||||
let sender_isk = [99; 32];
|
let sender_vsk = [99; 32];
|
||||||
let sender_ipk = IncomingViewingPublicKey::from_scalar(sender_isk);
|
let sender_vpk = ViewingPublicKey::from_scalar(sender_vsk);
|
||||||
let sender_npk = NullifierPublicKey::from(&sender_nsk);
|
let sender_npk = NullifierPublicKey::from(&sender_nsk);
|
||||||
let sender_pre = AccountWithMetadata::new(
|
let sender_pre = AccountWithMetadata::new(
|
||||||
Account {
|
Account {
|
||||||
@ -206,18 +206,18 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
|||||||
AccountId::from(&sender_npk),
|
AccountId::from(&sender_npk),
|
||||||
);
|
);
|
||||||
let recipient_nsk = [2; 32];
|
let recipient_nsk = [2; 32];
|
||||||
let recipient_isk = [99; 32];
|
let recipient_vsk = [99; 32];
|
||||||
let recipient_ipk = IncomingViewingPublicKey::from_scalar(recipient_isk);
|
let recipient_vpk = ViewingPublicKey::from_scalar(recipient_vsk);
|
||||||
let recipient_npk = NullifierPublicKey::from(&recipient_nsk);
|
let recipient_npk = NullifierPublicKey::from(&recipient_nsk);
|
||||||
let recipient_pre =
|
let recipient_pre =
|
||||||
AccountWithMetadata::new(Account::default(), false, AccountId::from(&recipient_npk));
|
AccountWithMetadata::new(Account::default(), false, AccountId::from(&recipient_npk));
|
||||||
|
|
||||||
let eph_holder_from = EphemeralKeyHolder::new(&sender_npk);
|
let eph_holder_from = EphemeralKeyHolder::new(&sender_npk);
|
||||||
let sender_ss = eph_holder_from.calculate_shared_secret_sender(&sender_ipk);
|
let sender_ss = eph_holder_from.calculate_shared_secret_sender(&sender_vpk);
|
||||||
let sender_epk = eph_holder_from.generate_ephemeral_public_key();
|
let sender_epk = eph_holder_from.generate_ephemeral_public_key();
|
||||||
|
|
||||||
let eph_holder_to = EphemeralKeyHolder::new(&recipient_npk);
|
let eph_holder_to = EphemeralKeyHolder::new(&recipient_npk);
|
||||||
let recipient_ss = eph_holder_to.calculate_shared_secret_sender(&recipient_ipk);
|
let recipient_ss = eph_holder_to.calculate_shared_secret_sender(&recipient_vpk);
|
||||||
let recipient_epk = eph_holder_from.generate_ephemeral_public_key();
|
let recipient_epk = eph_holder_from.generate_ephemeral_public_key();
|
||||||
|
|
||||||
let balance_to_move: u128 = 1;
|
let balance_to_move: u128 = 1;
|
||||||
@ -246,8 +246,8 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
|||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
vec![
|
vec![
|
||||||
(sender_npk, sender_ipk, sender_epk),
|
(sender_npk, sender_vpk, sender_epk),
|
||||||
(recipient_npk, recipient_ipk, recipient_epk),
|
(recipient_npk, recipient_vpk, recipient_epk),
|
||||||
],
|
],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use std::{
|
|||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
ffi::{CStr, CString, c_char},
|
ffi::{CStr, CString, c_char},
|
||||||
io::Write,
|
io::Write,
|
||||||
|
path::Path,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -24,6 +25,11 @@ unsafe extern "C" {
|
|||||||
password: *const c_char,
|
password: *const c_char,
|
||||||
) -> *mut WalletHandle;
|
) -> *mut WalletHandle;
|
||||||
|
|
||||||
|
fn wallet_ffi_open(
|
||||||
|
config_path: *const c_char,
|
||||||
|
storage_path: *const c_char,
|
||||||
|
) -> *mut WalletHandle;
|
||||||
|
|
||||||
fn wallet_ffi_destroy(handle: *mut WalletHandle);
|
fn wallet_ffi_destroy(handle: *mut WalletHandle);
|
||||||
|
|
||||||
fn wallet_ffi_create_account_public(
|
fn wallet_ffi_create_account_public(
|
||||||
@ -56,6 +62,12 @@ unsafe extern "C" {
|
|||||||
out_account: *mut FfiAccount,
|
out_account: *mut FfiAccount,
|
||||||
) -> error::WalletFfiError;
|
) -> error::WalletFfiError;
|
||||||
|
|
||||||
|
fn wallet_ffi_get_account_private(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
account_id: *const FfiBytes32,
|
||||||
|
out_account: *mut FfiAccount,
|
||||||
|
) -> error::WalletFfiError;
|
||||||
|
|
||||||
fn wallet_ffi_free_account_data(account: *mut FfiAccount);
|
fn wallet_ffi_free_account_data(account: *mut FfiAccount);
|
||||||
|
|
||||||
fn wallet_ffi_get_public_account_key(
|
fn wallet_ffi_get_public_account_key(
|
||||||
@ -89,6 +101,30 @@ unsafe extern "C" {
|
|||||||
out_result: *mut FfiTransferResult,
|
out_result: *mut FfiTransferResult,
|
||||||
) -> error::WalletFfiError;
|
) -> error::WalletFfiError;
|
||||||
|
|
||||||
|
fn wallet_ffi_transfer_shielded(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
from: *const FfiBytes32,
|
||||||
|
to_keys: *const FfiPrivateAccountKeys,
|
||||||
|
amount: *const [u8; 16],
|
||||||
|
out_result: *mut FfiTransferResult,
|
||||||
|
) -> error::WalletFfiError;
|
||||||
|
|
||||||
|
fn wallet_ffi_transfer_deshielded(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
from: *const FfiBytes32,
|
||||||
|
to: *const FfiBytes32,
|
||||||
|
amount: *const [u8; 16],
|
||||||
|
out_result: *mut FfiTransferResult,
|
||||||
|
) -> error::WalletFfiError;
|
||||||
|
|
||||||
|
fn wallet_ffi_transfer_private(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
from: *const FfiBytes32,
|
||||||
|
to_keys: *const FfiPrivateAccountKeys,
|
||||||
|
amount: *const [u8; 16],
|
||||||
|
out_result: *mut FfiTransferResult,
|
||||||
|
) -> error::WalletFfiError;
|
||||||
|
|
||||||
fn wallet_ffi_free_transfer_result(result: *mut FfiTransferResult);
|
fn wallet_ffi_free_transfer_result(result: *mut FfiTransferResult);
|
||||||
|
|
||||||
fn wallet_ffi_register_public_account(
|
fn wallet_ffi_register_public_account(
|
||||||
@ -96,12 +132,29 @@ unsafe extern "C" {
|
|||||||
account_id: *const FfiBytes32,
|
account_id: *const FfiBytes32,
|
||||||
out_result: *mut FfiTransferResult,
|
out_result: *mut FfiTransferResult,
|
||||||
) -> error::WalletFfiError;
|
) -> error::WalletFfiError;
|
||||||
|
|
||||||
|
fn wallet_ffi_register_private_account(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
account_id: *const FfiBytes32,
|
||||||
|
out_result: *mut FfiTransferResult,
|
||||||
|
) -> error::WalletFfiError;
|
||||||
|
|
||||||
|
fn wallet_ffi_save(handle: *mut WalletHandle) -> error::WalletFfiError;
|
||||||
|
|
||||||
|
fn wallet_ffi_sync_to_block(handle: *mut WalletHandle, block_id: u64) -> error::WalletFfiError;
|
||||||
|
|
||||||
|
fn wallet_ffi_get_current_block_height(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
out_block_height: *mut u64,
|
||||||
|
) -> error::WalletFfiError;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_wallet_ffi_with_test_context_config(ctx: &BlockingTestContext) -> *mut WalletHandle {
|
fn new_wallet_ffi_with_test_context_config(
|
||||||
let tempdir = tempfile::tempdir().unwrap();
|
ctx: &BlockingTestContext,
|
||||||
let config_path = tempdir.path().join("wallet_config.json");
|
home: &Path,
|
||||||
let storage_path = tempdir.path().join("storage.json");
|
) -> *mut WalletHandle {
|
||||||
|
let config_path = home.join("wallet_config.json");
|
||||||
|
let storage_path = home.join("storage.json");
|
||||||
let mut config = ctx.ctx().wallet().config().to_owned();
|
let mut config = ctx.ctx().wallet().config().to_owned();
|
||||||
if let Some(config_overrides) = ctx.ctx().wallet().config_overrides().clone() {
|
if let Some(config_overrides) = ctx.ctx().wallet().config_overrides().clone() {
|
||||||
config.apply_overrides(config_overrides);
|
config.apply_overrides(config_overrides);
|
||||||
@ -161,6 +214,15 @@ fn new_wallet_rust_with_default_config(password: &str) -> WalletCore {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_existing_ffi_wallet(home: &Path) -> *mut WalletHandle {
|
||||||
|
let config_path = home.join("wallet_config.json");
|
||||||
|
let storage_path = home.join("storage.json");
|
||||||
|
let config_path = CString::new(config_path.to_str().unwrap()).unwrap();
|
||||||
|
let storage_path = CString::new(storage_path.to_str().unwrap()).unwrap();
|
||||||
|
|
||||||
|
unsafe { wallet_ffi_open(config_path.as_ptr(), storage_path.as_ptr()) }
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wallet_ffi_create_public_accounts() {
|
fn test_wallet_ffi_create_public_accounts() {
|
||||||
let password = "password_for_tests";
|
let password = "password_for_tests";
|
||||||
@ -232,6 +294,56 @@ fn test_wallet_ffi_create_private_accounts() {
|
|||||||
|
|
||||||
assert_eq!(new_private_account_ids_ffi, new_private_account_ids_rust)
|
assert_eq!(new_private_account_ids_ffi, new_private_account_ids_rust)
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_wallet_ffi_save_and_load_persistent_storage() -> Result<()> {
|
||||||
|
let ctx = BlockingTestContext::new()?;
|
||||||
|
let mut out_private_account_id = FfiBytes32::from_bytes([0; 32]);
|
||||||
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
|
||||||
|
// Create a private account with the wallet FFI and save it
|
||||||
|
unsafe {
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
|
wallet_ffi_create_account_private(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&mut out_private_account_id) as *mut FfiBytes32,
|
||||||
|
);
|
||||||
|
|
||||||
|
wallet_ffi_save(wallet_ffi_handle);
|
||||||
|
wallet_ffi_destroy(wallet_ffi_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
let private_account_keys = unsafe {
|
||||||
|
let wallet_ffi_handle = load_existing_ffi_wallet(home.path());
|
||||||
|
|
||||||
|
let mut private_account = FfiAccount::default();
|
||||||
|
|
||||||
|
let result = wallet_ffi_get_account_private(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&out_private_account_id) as *const FfiBytes32,
|
||||||
|
(&mut private_account) as *mut FfiAccount,
|
||||||
|
);
|
||||||
|
assert_eq!(result, error::WalletFfiError::Success);
|
||||||
|
|
||||||
|
let mut out_keys = FfiPrivateAccountKeys::default();
|
||||||
|
let result = wallet_ffi_get_private_account_keys(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&out_private_account_id) as *const FfiBytes32,
|
||||||
|
(&mut out_keys) as *mut FfiPrivateAccountKeys,
|
||||||
|
);
|
||||||
|
assert_eq!(result, error::WalletFfiError::Success);
|
||||||
|
|
||||||
|
wallet_ffi_destroy(wallet_ffi_handle);
|
||||||
|
|
||||||
|
out_keys
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
nssa::AccountId::from(&private_account_keys.npk()),
|
||||||
|
out_private_account_id.into()
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wallet_ffi_list_accounts() {
|
fn test_wallet_ffi_list_accounts() {
|
||||||
@ -326,7 +438,8 @@ fn test_wallet_ffi_list_accounts() {
|
|||||||
fn test_wallet_ffi_get_balance_public() -> Result<()> {
|
fn test_wallet_ffi_get_balance_public() -> Result<()> {
|
||||||
let ctx = BlockingTestContext::new()?;
|
let ctx = BlockingTestContext::new()?;
|
||||||
let account_id: AccountId = ctx.ctx().existing_public_accounts()[0];
|
let account_id: AccountId = ctx.ctx().existing_public_accounts()[0];
|
||||||
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
|
|
||||||
let balance = unsafe {
|
let balance = unsafe {
|
||||||
let mut out_balance: [u8; 16] = [0; 16];
|
let mut out_balance: [u8; 16] = [0; 16];
|
||||||
@ -354,7 +467,8 @@ fn test_wallet_ffi_get_balance_public() -> Result<()> {
|
|||||||
fn test_wallet_ffi_get_account_public() -> Result<()> {
|
fn test_wallet_ffi_get_account_public() -> Result<()> {
|
||||||
let ctx = BlockingTestContext::new()?;
|
let ctx = BlockingTestContext::new()?;
|
||||||
let account_id: AccountId = ctx.ctx().existing_public_accounts()[0];
|
let account_id: AccountId = ctx.ctx().existing_public_accounts()[0];
|
||||||
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
let mut out_account = FfiAccount::default();
|
let mut out_account = FfiAccount::default();
|
||||||
|
|
||||||
let account: Account = unsafe {
|
let account: Account = unsafe {
|
||||||
@ -385,11 +499,48 @@ fn test_wallet_ffi_get_account_public() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wallet_ffi_get_account_private() -> Result<()> {
|
||||||
|
let ctx = BlockingTestContext::new()?;
|
||||||
|
let account_id: AccountId = ctx.ctx().existing_private_accounts()[0];
|
||||||
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
|
let mut out_account = FfiAccount::default();
|
||||||
|
|
||||||
|
let account: Account = unsafe {
|
||||||
|
let ffi_account_id = FfiBytes32::from(&account_id);
|
||||||
|
let _result = wallet_ffi_get_account_private(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&ffi_account_id) as *const FfiBytes32,
|
||||||
|
(&mut out_account) as *mut FfiAccount,
|
||||||
|
);
|
||||||
|
(&out_account).try_into().unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
account.program_owner,
|
||||||
|
Program::authenticated_transfer_program().id()
|
||||||
|
);
|
||||||
|
assert_eq!(account.balance, 10000);
|
||||||
|
assert!(account.data.is_empty());
|
||||||
|
assert_eq!(account.nonce, 0);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
wallet_ffi_free_account_data((&mut out_account) as *mut FfiAccount);
|
||||||
|
wallet_ffi_destroy(wallet_ffi_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Successfully retrieved account with correct details");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wallet_ffi_get_public_account_keys() -> Result<()> {
|
fn test_wallet_ffi_get_public_account_keys() -> Result<()> {
|
||||||
let ctx = BlockingTestContext::new()?;
|
let ctx = BlockingTestContext::new()?;
|
||||||
let account_id: AccountId = ctx.ctx().existing_public_accounts()[0];
|
let account_id: AccountId = ctx.ctx().existing_public_accounts()[0];
|
||||||
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
let mut out_key = FfiPublicAccountKey::default();
|
let mut out_key = FfiPublicAccountKey::default();
|
||||||
|
|
||||||
let key: PublicKey = unsafe {
|
let key: PublicKey = unsafe {
|
||||||
@ -426,7 +577,8 @@ fn test_wallet_ffi_get_public_account_keys() -> Result<()> {
|
|||||||
fn test_wallet_ffi_get_private_account_keys() -> Result<()> {
|
fn test_wallet_ffi_get_private_account_keys() -> Result<()> {
|
||||||
let ctx = BlockingTestContext::new()?;
|
let ctx = BlockingTestContext::new()?;
|
||||||
let account_id: AccountId = ctx.ctx().existing_private_accounts()[0];
|
let account_id: AccountId = ctx.ctx().existing_private_accounts()[0];
|
||||||
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
let mut keys = FfiPrivateAccountKeys::default();
|
let mut keys = FfiPrivateAccountKeys::default();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -448,10 +600,10 @@ fn test_wallet_ffi_get_private_account_keys() -> Result<()> {
|
|||||||
.0;
|
.0;
|
||||||
|
|
||||||
let expected_npk = &key_chain.nullifer_public_key;
|
let expected_npk = &key_chain.nullifer_public_key;
|
||||||
let expected_ivk = &key_chain.incoming_viewing_public_key;
|
let expected_vpk = &key_chain.viewing_public_key;
|
||||||
|
|
||||||
assert_eq!(&keys.npk(), expected_npk);
|
assert_eq!(&keys.npk(), expected_npk);
|
||||||
assert_eq!(&keys.ivk().unwrap(), expected_ivk);
|
assert_eq!(&keys.vpk().unwrap(), expected_vpk);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
wallet_ffi_free_private_account_keys((&mut keys) as *mut FfiPrivateAccountKeys);
|
wallet_ffi_free_private_account_keys((&mut keys) as *mut FfiPrivateAccountKeys);
|
||||||
@ -504,7 +656,8 @@ fn test_wallet_ffi_base58_to_account_id() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_wallet_ffi_init_public_account_auth_transfer() -> Result<()> {
|
fn test_wallet_ffi_init_public_account_auth_transfer() -> Result<()> {
|
||||||
let ctx = BlockingTestContext::new().unwrap();
|
let ctx = BlockingTestContext::new().unwrap();
|
||||||
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
|
|
||||||
// Create a new uninitialized public account
|
// Create a new uninitialized public account
|
||||||
let mut out_account_id = FfiBytes32::from_bytes([0; 32]);
|
let mut out_account_id = FfiBytes32::from_bytes([0; 32]);
|
||||||
@ -563,10 +716,81 @@ fn test_wallet_ffi_init_public_account_auth_transfer() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wallet_ffi_init_private_account_auth_transfer() -> Result<()> {
|
||||||
|
let ctx = BlockingTestContext::new().unwrap();
|
||||||
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
|
|
||||||
|
// Create a new uninitialized public account
|
||||||
|
let mut out_account_id = FfiBytes32::from_bytes([0; 32]);
|
||||||
|
unsafe {
|
||||||
|
wallet_ffi_create_account_private(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&mut out_account_id) as *mut FfiBytes32,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check its program owner is the default program id
|
||||||
|
let account: Account = unsafe {
|
||||||
|
let mut out_account = FfiAccount::default();
|
||||||
|
wallet_ffi_get_account_private(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&out_account_id) as *const FfiBytes32,
|
||||||
|
(&mut out_account) as *mut FfiAccount,
|
||||||
|
);
|
||||||
|
(&out_account).try_into().unwrap()
|
||||||
|
};
|
||||||
|
assert_eq!(account.program_owner, DEFAULT_PROGRAM_ID);
|
||||||
|
|
||||||
|
// Call the init funciton
|
||||||
|
let mut transfer_result = FfiTransferResult::default();
|
||||||
|
unsafe {
|
||||||
|
wallet_ffi_register_private_account(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&out_account_id) as *const FfiBytes32,
|
||||||
|
(&mut transfer_result) as *mut FfiTransferResult,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Waiting for next block creation");
|
||||||
|
std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS));
|
||||||
|
|
||||||
|
// Sync private account local storage with onchain encrypted state
|
||||||
|
unsafe {
|
||||||
|
let mut current_height = 0;
|
||||||
|
wallet_ffi_get_current_block_height(wallet_ffi_handle, (&mut current_height) as *mut u64);
|
||||||
|
wallet_ffi_sync_to_block(wallet_ffi_handle, current_height);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check that the program owner is now the authenticated transfer program
|
||||||
|
let account: Account = unsafe {
|
||||||
|
let mut out_account = FfiAccount::default();
|
||||||
|
let _result = wallet_ffi_get_account_private(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&out_account_id) as *const FfiBytes32,
|
||||||
|
(&mut out_account) as *mut FfiAccount,
|
||||||
|
);
|
||||||
|
(&out_account).try_into().unwrap()
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
account.program_owner,
|
||||||
|
Program::authenticated_transfer_program().id()
|
||||||
|
);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
wallet_ffi_free_transfer_result((&mut transfer_result) as *mut FfiTransferResult);
|
||||||
|
wallet_ffi_destroy(wallet_ffi_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wallet_ffi_transfer_public() -> Result<()> {
|
fn test_wallet_ffi_transfer_public() -> Result<()> {
|
||||||
let ctx = BlockingTestContext::new().unwrap();
|
let ctx = BlockingTestContext::new().unwrap();
|
||||||
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
let from: FfiBytes32 = (&ctx.ctx().existing_public_accounts()[0]).into();
|
let from: FfiBytes32 = (&ctx.ctx().existing_public_accounts()[0]).into();
|
||||||
let to: FfiBytes32 = (&ctx.ctx().existing_public_accounts()[1]).into();
|
let to: FfiBytes32 = (&ctx.ctx().existing_public_accounts()[1]).into();
|
||||||
let amount: [u8; 16] = 100u128.to_le_bytes();
|
let amount: [u8; 16] = 100u128.to_le_bytes();
|
||||||
@ -617,3 +841,220 @@ fn test_wallet_ffi_transfer_public() -> Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wallet_ffi_transfer_shielded() -> Result<()> {
|
||||||
|
let ctx = BlockingTestContext::new().unwrap();
|
||||||
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
|
let from: FfiBytes32 = (&ctx.ctx().existing_public_accounts()[0]).into();
|
||||||
|
let (to, to_keys) = unsafe {
|
||||||
|
let mut out_account_id = FfiBytes32::default();
|
||||||
|
let mut out_keys = FfiPrivateAccountKeys::default();
|
||||||
|
wallet_ffi_create_account_private(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&mut out_account_id) as *mut FfiBytes32,
|
||||||
|
);
|
||||||
|
wallet_ffi_get_private_account_keys(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&out_account_id) as *const FfiBytes32,
|
||||||
|
(&mut out_keys) as *mut FfiPrivateAccountKeys,
|
||||||
|
);
|
||||||
|
(out_account_id, out_keys)
|
||||||
|
};
|
||||||
|
let amount: [u8; 16] = 100u128.to_le_bytes();
|
||||||
|
|
||||||
|
let mut transfer_result = FfiTransferResult::default();
|
||||||
|
unsafe {
|
||||||
|
wallet_ffi_transfer_shielded(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&from) as *const FfiBytes32,
|
||||||
|
(&to_keys) as *const FfiPrivateAccountKeys,
|
||||||
|
(&amount) as *const [u8; 16],
|
||||||
|
(&mut transfer_result) as *mut FfiTransferResult,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Waiting for next block creation");
|
||||||
|
std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS));
|
||||||
|
|
||||||
|
// Sync private account local storage with onchain encrypted state
|
||||||
|
unsafe {
|
||||||
|
let mut current_height = 0;
|
||||||
|
wallet_ffi_get_current_block_height(wallet_ffi_handle, (&mut current_height) as *mut u64);
|
||||||
|
wallet_ffi_sync_to_block(wallet_ffi_handle, current_height);
|
||||||
|
};
|
||||||
|
|
||||||
|
let from_balance = unsafe {
|
||||||
|
let mut out_balance: [u8; 16] = [0; 16];
|
||||||
|
let _result = wallet_ffi_get_balance(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&from) as *const FfiBytes32,
|
||||||
|
true,
|
||||||
|
(&mut out_balance) as *mut [u8; 16],
|
||||||
|
);
|
||||||
|
u128::from_le_bytes(out_balance)
|
||||||
|
};
|
||||||
|
|
||||||
|
let to_balance = unsafe {
|
||||||
|
let mut out_balance: [u8; 16] = [0; 16];
|
||||||
|
let _result = wallet_ffi_get_balance(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&to) as *const FfiBytes32,
|
||||||
|
false,
|
||||||
|
(&mut out_balance) as *mut [u8; 16],
|
||||||
|
);
|
||||||
|
u128::from_le_bytes(out_balance)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(from_balance, 9900);
|
||||||
|
assert_eq!(to_balance, 100);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
wallet_ffi_free_transfer_result((&mut transfer_result) as *mut FfiTransferResult);
|
||||||
|
wallet_ffi_destroy(wallet_ffi_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wallet_ffi_transfer_deshielded() -> Result<()> {
|
||||||
|
let ctx = BlockingTestContext::new().unwrap();
|
||||||
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
|
let from: FfiBytes32 = (&ctx.ctx().existing_private_accounts()[0]).into();
|
||||||
|
let to = FfiBytes32::from_bytes([37; 32]);
|
||||||
|
let amount: [u8; 16] = 100u128.to_le_bytes();
|
||||||
|
|
||||||
|
let mut transfer_result = FfiTransferResult::default();
|
||||||
|
unsafe {
|
||||||
|
wallet_ffi_transfer_deshielded(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&from) as *const FfiBytes32,
|
||||||
|
(&to) as *const FfiBytes32,
|
||||||
|
(&amount) as *const [u8; 16],
|
||||||
|
(&mut transfer_result) as *mut FfiTransferResult,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Waiting for next block creation");
|
||||||
|
std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS));
|
||||||
|
|
||||||
|
// Sync private account local storage with onchain encrypted state
|
||||||
|
unsafe {
|
||||||
|
let mut current_height = 0;
|
||||||
|
wallet_ffi_get_current_block_height(wallet_ffi_handle, (&mut current_height) as *mut u64);
|
||||||
|
wallet_ffi_sync_to_block(wallet_ffi_handle, current_height);
|
||||||
|
};
|
||||||
|
|
||||||
|
let from_balance = unsafe {
|
||||||
|
let mut out_balance: [u8; 16] = [0; 16];
|
||||||
|
let _result = wallet_ffi_get_balance(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&from) as *const FfiBytes32,
|
||||||
|
false,
|
||||||
|
(&mut out_balance) as *mut [u8; 16],
|
||||||
|
);
|
||||||
|
u128::from_le_bytes(out_balance)
|
||||||
|
};
|
||||||
|
|
||||||
|
let to_balance = unsafe {
|
||||||
|
let mut out_balance: [u8; 16] = [0; 16];
|
||||||
|
let _result = wallet_ffi_get_balance(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&to) as *const FfiBytes32,
|
||||||
|
true,
|
||||||
|
(&mut out_balance) as *mut [u8; 16],
|
||||||
|
);
|
||||||
|
u128::from_le_bytes(out_balance)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(from_balance, 9900);
|
||||||
|
assert_eq!(to_balance, 100);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
wallet_ffi_free_transfer_result((&mut transfer_result) as *mut FfiTransferResult);
|
||||||
|
wallet_ffi_destroy(wallet_ffi_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wallet_ffi_transfer_private() -> Result<()> {
|
||||||
|
let ctx = BlockingTestContext::new().unwrap();
|
||||||
|
let home = tempfile::tempdir().unwrap();
|
||||||
|
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx, home.path());
|
||||||
|
|
||||||
|
let from: FfiBytes32 = (&ctx.ctx().existing_private_accounts()[0]).into();
|
||||||
|
let (to, to_keys) = unsafe {
|
||||||
|
let mut out_account_id = FfiBytes32::default();
|
||||||
|
let mut out_keys = FfiPrivateAccountKeys::default();
|
||||||
|
wallet_ffi_create_account_private(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&mut out_account_id) as *mut FfiBytes32,
|
||||||
|
);
|
||||||
|
wallet_ffi_get_private_account_keys(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&out_account_id) as *const FfiBytes32,
|
||||||
|
(&mut out_keys) as *mut FfiPrivateAccountKeys,
|
||||||
|
);
|
||||||
|
(out_account_id, out_keys)
|
||||||
|
};
|
||||||
|
|
||||||
|
let amount: [u8; 16] = 100u128.to_le_bytes();
|
||||||
|
|
||||||
|
let mut transfer_result = FfiTransferResult::default();
|
||||||
|
unsafe {
|
||||||
|
wallet_ffi_transfer_private(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&from) as *const FfiBytes32,
|
||||||
|
(&to_keys) as *const FfiPrivateAccountKeys,
|
||||||
|
(&amount) as *const [u8; 16],
|
||||||
|
(&mut transfer_result) as *mut FfiTransferResult,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Waiting for next block creation");
|
||||||
|
std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS));
|
||||||
|
|
||||||
|
// Sync private account local storage with onchain encrypted state
|
||||||
|
unsafe {
|
||||||
|
let mut current_height = 0;
|
||||||
|
wallet_ffi_get_current_block_height(wallet_ffi_handle, (&mut current_height) as *mut u64);
|
||||||
|
wallet_ffi_sync_to_block(wallet_ffi_handle, current_height);
|
||||||
|
};
|
||||||
|
|
||||||
|
let from_balance = unsafe {
|
||||||
|
let mut out_balance: [u8; 16] = [0; 16];
|
||||||
|
let _result = wallet_ffi_get_balance(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&from) as *const FfiBytes32,
|
||||||
|
false,
|
||||||
|
(&mut out_balance) as *mut [u8; 16],
|
||||||
|
);
|
||||||
|
u128::from_le_bytes(out_balance)
|
||||||
|
};
|
||||||
|
|
||||||
|
let to_balance = unsafe {
|
||||||
|
let mut out_balance: [u8; 16] = [0; 16];
|
||||||
|
let _result = wallet_ffi_get_balance(
|
||||||
|
wallet_ffi_handle,
|
||||||
|
(&to) as *const FfiBytes32,
|
||||||
|
false,
|
||||||
|
(&mut out_balance) as *mut [u8; 16],
|
||||||
|
);
|
||||||
|
u128::from_le_bytes(out_balance)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(from_balance, 9900);
|
||||||
|
assert_eq!(to_balance, 100);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
wallet_ffi_free_transfer_result((&mut transfer_result) as *mut FfiTransferResult);
|
||||||
|
wallet_ffi_destroy(wallet_ffi_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
NullifierPublicKey, SharedSecretKey,
|
NullifierPublicKey, SharedSecretKey,
|
||||||
encryption::{EphemeralPublicKey, EphemeralSecretKey, IncomingViewingPublicKey},
|
encryption::{EphemeralPublicKey, EphemeralSecretKey, ViewingPublicKey},
|
||||||
};
|
};
|
||||||
use rand::{RngCore, rngs::OsRng};
|
use rand::{RngCore, rngs::OsRng};
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
@ -13,12 +13,12 @@ pub struct EphemeralKeyHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn produce_one_sided_shared_secret_receiver(
|
pub fn produce_one_sided_shared_secret_receiver(
|
||||||
ipk: &IncomingViewingPublicKey,
|
vpk: &ViewingPublicKey,
|
||||||
) -> (SharedSecretKey, EphemeralPublicKey) {
|
) -> (SharedSecretKey, EphemeralPublicKey) {
|
||||||
let mut esk = [0; 32];
|
let mut esk = [0; 32];
|
||||||
OsRng.fill_bytes(&mut esk);
|
OsRng.fill_bytes(&mut esk);
|
||||||
(
|
(
|
||||||
SharedSecretKey::new(&esk, ipk),
|
SharedSecretKey::new(&esk, vpk),
|
||||||
EphemeralPublicKey::from_scalar(esk),
|
EphemeralPublicKey::from_scalar(esk),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -42,11 +42,8 @@ impl EphemeralKeyHolder {
|
|||||||
|
|
||||||
pub fn calculate_shared_secret_sender(
|
pub fn calculate_shared_secret_sender(
|
||||||
&self,
|
&self,
|
||||||
receiver_incoming_viewing_public_key: &IncomingViewingPublicKey,
|
receiver_viewing_public_key: &ViewingPublicKey,
|
||||||
) -> SharedSecretKey {
|
) -> SharedSecretKey {
|
||||||
SharedSecretKey::new(
|
SharedSecretKey::new(&self.ephemeral_secret_key, receiver_viewing_public_key)
|
||||||
&self.ephemeral_secret_key,
|
|
||||||
receiver_incoming_viewing_public_key,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use k256::{Scalar, elliptic_curve::PrimeField};
|
use k256::{Scalar, elliptic_curve::PrimeField};
|
||||||
use nssa_core::encryption::IncomingViewingPublicKey;
|
use nssa_core::{NullifierPublicKey, encryption::ViewingPublicKey};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::key_management::{
|
use crate::key_management::{
|
||||||
@ -18,7 +18,7 @@ pub struct ChildKeysPrivate {
|
|||||||
|
|
||||||
impl KeyNode for ChildKeysPrivate {
|
impl KeyNode for ChildKeysPrivate {
|
||||||
fn root(seed: [u8; 64]) -> Self {
|
fn root(seed: [u8; 64]) -> Self {
|
||||||
let hash_value = hmac_sha512::HMAC::mac(seed, "NSSA_master_priv");
|
let hash_value = hmac_sha512::HMAC::mac(seed, b"LEE_master_priv");
|
||||||
|
|
||||||
let ssk = SecretSpendingKey(
|
let ssk = SecretSpendingKey(
|
||||||
*hash_value
|
*hash_value
|
||||||
@ -29,23 +29,21 @@ impl KeyNode for ChildKeysPrivate {
|
|||||||
.last_chunk::<32>()
|
.last_chunk::<32>()
|
||||||
.expect("hash_value is 64 bytes, must be safe to get last 32");
|
.expect("hash_value is 64 bytes, must be safe to get last 32");
|
||||||
|
|
||||||
let nsk = ssk.generate_nullifier_secret_key();
|
let nsk = ssk.generate_nullifier_secret_key(None);
|
||||||
let isk = ssk.generate_incoming_viewing_secret_key();
|
let vsk = ssk.generate_viewing_secret_key(None);
|
||||||
let ovk = ssk.generate_outgoing_viewing_secret_key();
|
|
||||||
|
|
||||||
let npk = (&nsk).into();
|
let npk = NullifierPublicKey::from(&nsk);
|
||||||
let ipk = IncomingViewingPublicKey::from_scalar(isk);
|
let vpk = ViewingPublicKey::from_scalar(vsk);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
value: (
|
value: (
|
||||||
KeyChain {
|
KeyChain {
|
||||||
secret_spending_key: ssk,
|
secret_spending_key: ssk,
|
||||||
nullifer_public_key: npk,
|
nullifer_public_key: npk,
|
||||||
incoming_viewing_public_key: ipk,
|
viewing_public_key: vpk,
|
||||||
private_key_holder: PrivateKeyHolder {
|
private_key_holder: PrivateKeyHolder {
|
||||||
nullifier_secret_key: nsk,
|
nullifier_secret_key: nsk,
|
||||||
incoming_viewing_secret_key: isk,
|
viewing_secret_key: vsk,
|
||||||
outgoing_viewing_secret_key: ovk,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nssa::Account::default(),
|
nssa::Account::default(),
|
||||||
@ -56,27 +54,14 @@ impl KeyNode for ChildKeysPrivate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn nth_child(&self, cci: u32) -> Self {
|
fn nth_child(&self, cci: u32) -> Self {
|
||||||
let parent_pt = Scalar::from_repr(
|
let parent_pt =
|
||||||
self.value
|
Scalar::from_repr(self.value.0.private_key_holder.nullifier_secret_key.into())
|
||||||
.0
|
|
||||||
.private_key_holder
|
|
||||||
.outgoing_viewing_secret_key
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.expect("Key generated as scalar, must be valid representation")
|
|
||||||
+ Scalar::from_repr(self.value.0.private_key_holder.nullifier_secret_key.into())
|
|
||||||
.expect("Key generated as scalar, must be valid representation")
|
.expect("Key generated as scalar, must be valid representation")
|
||||||
* Scalar::from_repr(
|
* Scalar::from_repr(self.value.0.private_key_holder.viewing_secret_key.into())
|
||||||
self.value
|
.expect("Key generated as scalar, must be valid representation");
|
||||||
.0
|
|
||||||
.private_key_holder
|
|
||||||
.incoming_viewing_secret_key
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.expect("Key generated as scalar, must be valid representation");
|
|
||||||
let mut input = vec![];
|
let mut input = vec![];
|
||||||
|
|
||||||
input.extend_from_slice(b"NSSA_seed_priv");
|
input.extend_from_slice(b"LEE_seed_priv");
|
||||||
input.extend_from_slice(&parent_pt.to_bytes());
|
input.extend_from_slice(&parent_pt.to_bytes());
|
||||||
input.extend_from_slice(&cci.to_le_bytes());
|
input.extend_from_slice(&cci.to_le_bytes());
|
||||||
|
|
||||||
@ -91,23 +76,21 @@ impl KeyNode for ChildKeysPrivate {
|
|||||||
.last_chunk::<32>()
|
.last_chunk::<32>()
|
||||||
.expect("hash_value is 64 bytes, must be safe to get last 32");
|
.expect("hash_value is 64 bytes, must be safe to get last 32");
|
||||||
|
|
||||||
let nsk = ssk.generate_nullifier_secret_key();
|
let nsk = ssk.generate_nullifier_secret_key(Some(cci));
|
||||||
let isk = ssk.generate_incoming_viewing_secret_key();
|
let vsk = ssk.generate_viewing_secret_key(Some(cci));
|
||||||
let ovk = ssk.generate_outgoing_viewing_secret_key();
|
|
||||||
|
|
||||||
let npk = (&nsk).into();
|
let npk = NullifierPublicKey::from(&nsk);
|
||||||
let ipk = IncomingViewingPublicKey::from_scalar(isk);
|
let vpk = ViewingPublicKey::from_scalar(vsk);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
value: (
|
value: (
|
||||||
KeyChain {
|
KeyChain {
|
||||||
secret_spending_key: ssk,
|
secret_spending_key: ssk,
|
||||||
nullifer_public_key: npk,
|
nullifer_public_key: npk,
|
||||||
incoming_viewing_public_key: ipk,
|
viewing_public_key: vpk,
|
||||||
private_key_holder: PrivateKeyHolder {
|
private_key_holder: PrivateKeyHolder {
|
||||||
nullifier_secret_key: nsk,
|
nullifier_secret_key: nsk,
|
||||||
incoming_viewing_secret_key: isk,
|
viewing_secret_key: vsk,
|
||||||
outgoing_viewing_secret_key: ovk,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nssa::Account::default(),
|
nssa::Account::default(),
|
||||||
@ -144,120 +127,98 @@ impl<'a> From<&'a mut ChildKeysPrivate> for &'a mut (KeyChain, nssa::Account) {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use nssa_core::{NullifierPublicKey, NullifierSecretKey};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::key_management::{self, secret_holders::ViewingSecretKey};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_keys_deterministic_generation() {
|
fn test_master_key_generation() {
|
||||||
let root_keys = ChildKeysPrivate::root([42; 64]);
|
let seed: [u8; 64] = [
|
||||||
let child_keys = root_keys.nth_child(5);
|
252, 56, 204, 83, 232, 123, 209, 188, 187, 167, 39, 213, 71, 39, 58, 65, 125, 134, 255,
|
||||||
|
49, 43, 108, 92, 53, 173, 164, 94, 142, 150, 74, 21, 163, 43, 144, 226, 87, 199, 18,
|
||||||
|
129, 223, 176, 198, 5, 150, 157, 70, 210, 254, 14, 105, 89, 191, 246, 27, 52, 170, 56,
|
||||||
|
114, 39, 38, 118, 197, 205, 225,
|
||||||
|
];
|
||||||
|
|
||||||
assert_eq!(root_keys.cci, None);
|
let keys = ChildKeysPrivate::root(seed);
|
||||||
assert_eq!(child_keys.cci, Some(5));
|
|
||||||
|
|
||||||
assert_eq!(
|
let expected_ssk: SecretSpendingKey = key_management::secret_holders::SecretSpendingKey([
|
||||||
root_keys.value.0.secret_spending_key.0,
|
246, 79, 26, 124, 135, 95, 52, 51, 201, 27, 48, 194, 2, 144, 51, 219, 245, 128, 139,
|
||||||
[
|
222, 42, 195, 105, 33, 115, 97, 186, 0, 97, 14, 218, 191,
|
||||||
249, 83, 253, 32, 174, 204, 185, 44, 253, 167, 61, 92, 128, 5, 152, 4, 220, 21, 88,
|
]);
|
||||||
84, 167, 180, 154, 249, 44, 77, 33, 136, 59, 131, 203, 152
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
child_keys.value.0.secret_spending_key.0,
|
|
||||||
[
|
|
||||||
16, 242, 229, 242, 252, 158, 153, 210, 234, 120, 70, 85, 83, 196, 5, 53, 28, 26,
|
|
||||||
187, 230, 22, 193, 146, 232, 237, 3, 166, 184, 122, 1, 233, 93
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
let expected_ccc = [
|
||||||
root_keys.value.0.private_key_holder.nullifier_secret_key,
|
56, 114, 70, 249, 67, 169, 206, 9, 192, 11, 180, 168, 149, 129, 42, 95, 43, 157, 130,
|
||||||
[
|
111, 13, 5, 195, 75, 20, 255, 162, 85, 40, 251, 8, 168,
|
||||||
38, 195, 52, 182, 16, 66, 167, 156, 9, 14, 65, 100, 17, 93, 166, 71, 27, 148, 93,
|
];
|
||||||
85, 116, 109, 130, 8, 195, 222, 159, 214, 141, 41, 124, 57
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
child_keys.value.0.private_key_holder.nullifier_secret_key,
|
|
||||||
[
|
|
||||||
215, 46, 2, 151, 174, 60, 86, 154, 5, 3, 175, 245, 12, 176, 220, 58, 250, 118, 236,
|
|
||||||
49, 254, 221, 229, 58, 40, 1, 170, 145, 175, 108, 23, 170
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
let expected_nsk: NullifierSecretKey = [
|
||||||
root_keys
|
154, 102, 103, 5, 34, 235, 227, 13, 22, 182, 226, 11, 7, 67, 110, 162, 99, 193, 174,
|
||||||
.value
|
34, 234, 19, 222, 2, 22, 12, 163, 252, 88, 11, 0, 163,
|
||||||
.0
|
];
|
||||||
.private_key_holder
|
|
||||||
.incoming_viewing_secret_key,
|
|
||||||
[
|
|
||||||
153, 161, 15, 34, 96, 184, 165, 165, 27, 244, 155, 40, 70, 5, 241, 133, 78, 40, 61,
|
|
||||||
118, 48, 148, 226, 5, 97, 18, 201, 128, 82, 248, 163, 72
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
child_keys
|
|
||||||
.value
|
|
||||||
.0
|
|
||||||
.private_key_holder
|
|
||||||
.incoming_viewing_secret_key,
|
|
||||||
[
|
|
||||||
192, 155, 55, 43, 164, 115, 71, 145, 227, 225, 21, 57, 55, 12, 226, 44, 10, 103,
|
|
||||||
39, 73, 230, 173, 60, 69, 69, 122, 110, 241, 164, 3, 192, 57
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
let expected_npk: NullifierPublicKey = nssa_core::NullifierPublicKey([
|
||||||
root_keys
|
7, 123, 125, 191, 233, 183, 201, 4, 20, 214, 155, 210, 45, 234, 27, 240, 194, 111, 97,
|
||||||
.value
|
247, 155, 113, 122, 246, 192, 0, 70, 61, 76, 71, 70, 2,
|
||||||
.0
|
]);
|
||||||
.private_key_holder
|
let expected_vsk: ViewingSecretKey = [
|
||||||
.outgoing_viewing_secret_key,
|
155, 90, 54, 75, 228, 130, 68, 201, 129, 251, 180, 195, 250, 64, 34, 230, 241, 204,
|
||||||
[
|
216, 50, 149, 156, 10, 67, 208, 74, 9, 10, 47, 59, 50, 202,
|
||||||
205, 87, 71, 129, 90, 242, 217, 200, 140, 252, 124, 46, 207, 7, 33, 156, 83, 166,
|
];
|
||||||
150, 81, 98, 131, 182, 156, 110, 92, 78, 140, 125, 218, 152, 154
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
child_keys
|
|
||||||
.value
|
|
||||||
.0
|
|
||||||
.private_key_holder
|
|
||||||
.outgoing_viewing_secret_key,
|
|
||||||
[
|
|
||||||
131, 202, 219, 172, 219, 29, 48, 120, 226, 209, 209, 10, 216, 173, 48, 167, 233,
|
|
||||||
17, 35, 155, 30, 217, 176, 120, 72, 146, 250, 226, 165, 178, 255, 90
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
let expected_vpk_as_bytes: [u8; 33] = [
|
||||||
root_keys.value.0.nullifer_public_key.0,
|
2, 191, 99, 102, 114, 40, 131, 109, 166, 8, 222, 186, 107, 29, 156, 106, 206, 96, 127,
|
||||||
[
|
80, 170, 66, 217, 79, 38, 80, 11, 74, 147, 123, 221, 159, 166,
|
||||||
65, 176, 149, 243, 192, 45, 216, 177, 169, 56, 229, 7, 28, 66, 204, 87, 109, 83,
|
];
|
||||||
152, 64, 14, 188, 179, 210, 147, 60, 22, 251, 203, 70, 89, 215
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
child_keys.value.0.nullifer_public_key.0,
|
|
||||||
[
|
|
||||||
69, 104, 130, 115, 48, 134, 19, 188, 67, 148, 163, 54, 155, 237, 57, 27, 136, 228,
|
|
||||||
111, 233, 205, 158, 149, 31, 84, 11, 241, 176, 243, 12, 138, 249
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert!(expected_ssk == keys.value.0.secret_spending_key);
|
||||||
root_keys.value.0.incoming_viewing_public_key.0,
|
assert!(expected_ccc == keys.ccc);
|
||||||
&[
|
assert!(expected_nsk == keys.value.0.private_key_holder.nullifier_secret_key);
|
||||||
3, 174, 56, 136, 244, 179, 18, 122, 38, 220, 36, 50, 200, 41, 104, 167, 70, 18, 60,
|
assert!(expected_npk == keys.value.0.nullifer_public_key);
|
||||||
202, 93, 193, 29, 16, 125, 252, 96, 51, 199, 152, 47, 233, 178
|
assert!(expected_vsk == keys.value.0.private_key_holder.viewing_secret_key);
|
||||||
]
|
assert!(expected_vpk_as_bytes == keys.value.0.viewing_public_key.to_bytes());
|
||||||
);
|
}
|
||||||
assert_eq!(
|
|
||||||
child_keys.value.0.incoming_viewing_public_key.0,
|
#[test]
|
||||||
&[
|
fn test_child_keys_generation() {
|
||||||
3, 18, 202, 246, 79, 141, 169, 51, 55, 202, 120, 169, 244, 201, 156, 162, 216, 115,
|
let seed: [u8; 64] = [
|
||||||
126, 53, 46, 94, 235, 125, 114, 178, 215, 81, 171, 93, 93, 88, 117
|
252, 56, 204, 83, 232, 123, 209, 188, 187, 167, 39, 213, 71, 39, 58, 65, 125, 134, 255,
|
||||||
]
|
49, 43, 108, 92, 53, 173, 164, 94, 142, 150, 74, 21, 163, 43, 144, 226, 87, 199, 18,
|
||||||
);
|
129, 223, 176, 198, 5, 150, 157, 70, 210, 254, 14, 105, 89, 191, 246, 27, 52, 170, 56,
|
||||||
|
114, 39, 38, 118, 197, 205, 225,
|
||||||
|
];
|
||||||
|
|
||||||
|
let root_node = ChildKeysPrivate::root(seed);
|
||||||
|
let child_node = ChildKeysPrivate::nth_child(&root_node, 42u32);
|
||||||
|
|
||||||
|
let expected_ccc: [u8; 32] = [
|
||||||
|
145, 59, 225, 32, 54, 168, 14, 45, 60, 253, 57, 202, 31, 86, 142, 234, 51, 57, 154, 88,
|
||||||
|
132, 200, 92, 191, 220, 144, 42, 184, 108, 35, 226, 146,
|
||||||
|
];
|
||||||
|
|
||||||
|
let expected_nsk: NullifierSecretKey = [
|
||||||
|
19, 100, 119, 73, 191, 225, 234, 219, 129, 88, 40, 229, 63, 225, 189, 136, 69, 172,
|
||||||
|
221, 186, 147, 83, 150, 207, 70, 17, 228, 70, 113, 87, 227, 31,
|
||||||
|
];
|
||||||
|
let expected_npk: NullifierPublicKey = nssa_core::NullifierPublicKey([
|
||||||
|
133, 235, 223, 151, 12, 69, 26, 222, 60, 125, 235, 125, 167, 212, 201, 168, 101, 242,
|
||||||
|
111, 239, 1, 228, 12, 252, 146, 53, 75, 17, 187, 255, 122, 181,
|
||||||
|
]);
|
||||||
|
|
||||||
|
let expected_vsk: ViewingSecretKey = [
|
||||||
|
218, 219, 193, 132, 160, 6, 178, 194, 139, 248, 199, 81, 17, 133, 37, 201, 58, 104, 49,
|
||||||
|
222, 187, 46, 156, 93, 14, 118, 209, 243, 38, 101, 77, 45,
|
||||||
|
];
|
||||||
|
let expected_vpk_as_bytes: [u8; 33] = [
|
||||||
|
3, 164, 65, 167, 88, 167, 179, 51, 159, 27, 241, 174, 77, 174, 142, 106, 128, 96, 69,
|
||||||
|
74, 117, 231, 42, 193, 235, 153, 206, 116, 102, 7, 101, 192, 45,
|
||||||
|
];
|
||||||
|
|
||||||
|
assert!(expected_ccc == child_node.ccc);
|
||||||
|
assert!(expected_nsk == child_node.value.0.private_key_holder.nullifier_secret_key);
|
||||||
|
assert!(expected_npk == child_node.value.0.nullifer_public_key);
|
||||||
|
assert!(expected_vsk == child_node.value.0.private_key_holder.viewing_secret_key);
|
||||||
|
assert!(expected_vpk_as_bytes == child_node.value.0.viewing_public_key.to_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
NullifierPublicKey, SharedSecretKey,
|
NullifierPublicKey, SharedSecretKey,
|
||||||
encryption::{EphemeralPublicKey, IncomingViewingPublicKey},
|
encryption::{EphemeralPublicKey, ViewingPublicKey},
|
||||||
};
|
};
|
||||||
use secret_holders::{PrivateKeyHolder, SecretSpendingKey, SeedHolder};
|
use secret_holders::{PrivateKeyHolder, SecretSpendingKey, SeedHolder};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -17,7 +17,7 @@ pub struct KeyChain {
|
|||||||
pub secret_spending_key: SecretSpendingKey,
|
pub secret_spending_key: SecretSpendingKey,
|
||||||
pub private_key_holder: PrivateKeyHolder,
|
pub private_key_holder: PrivateKeyHolder,
|
||||||
pub nullifer_public_key: NullifierPublicKey,
|
pub nullifer_public_key: NullifierPublicKey,
|
||||||
pub incoming_viewing_public_key: IncomingViewingPublicKey,
|
pub viewing_public_key: ViewingPublicKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyChain {
|
impl KeyChain {
|
||||||
@ -27,16 +27,16 @@ impl KeyChain {
|
|||||||
let seed_holder = SeedHolder::new_os_random();
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
let secret_spending_key = seed_holder.produce_top_secret_key_holder();
|
let secret_spending_key = seed_holder.produce_top_secret_key_holder();
|
||||||
|
|
||||||
let private_key_holder = secret_spending_key.produce_private_key_holder();
|
let private_key_holder = secret_spending_key.produce_private_key_holder(None);
|
||||||
|
|
||||||
let nullifer_public_key = private_key_holder.generate_nullifier_public_key();
|
let nullifer_public_key = private_key_holder.generate_nullifier_public_key();
|
||||||
let incoming_viewing_public_key = private_key_holder.generate_incoming_viewing_public_key();
|
let viewing_public_key = private_key_holder.generate_viewing_public_key();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
secret_spending_key,
|
secret_spending_key,
|
||||||
private_key_holder,
|
private_key_holder,
|
||||||
nullifer_public_key,
|
nullifer_public_key,
|
||||||
incoming_viewing_public_key,
|
viewing_public_key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,16 +46,16 @@ impl KeyChain {
|
|||||||
let seed_holder = SeedHolder::new_mnemonic(passphrase);
|
let seed_holder = SeedHolder::new_mnemonic(passphrase);
|
||||||
let secret_spending_key = seed_holder.produce_top_secret_key_holder();
|
let secret_spending_key = seed_holder.produce_top_secret_key_holder();
|
||||||
|
|
||||||
let private_key_holder = secret_spending_key.produce_private_key_holder();
|
let private_key_holder = secret_spending_key.produce_private_key_holder(None);
|
||||||
|
|
||||||
let nullifer_public_key = private_key_holder.generate_nullifier_public_key();
|
let nullifer_public_key = private_key_holder.generate_nullifier_public_key();
|
||||||
let incoming_viewing_public_key = private_key_holder.generate_incoming_viewing_public_key();
|
let viewing_public_key = private_key_holder.generate_viewing_public_key();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
secret_spending_key,
|
secret_spending_key,
|
||||||
private_key_holder,
|
private_key_holder,
|
||||||
nullifer_public_key,
|
nullifer_public_key,
|
||||||
incoming_viewing_public_key,
|
viewing_public_key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,9 +64,7 @@ impl KeyChain {
|
|||||||
ephemeral_public_key_sender: EphemeralPublicKey,
|
ephemeral_public_key_sender: EphemeralPublicKey,
|
||||||
) -> SharedSecretKey {
|
) -> SharedSecretKey {
|
||||||
SharedSecretKey::new(
|
SharedSecretKey::new(
|
||||||
&self
|
&self.secret_spending_key.generate_viewing_secret_key(None),
|
||||||
.secret_spending_key
|
|
||||||
.generate_incoming_viewing_secret_key(),
|
|
||||||
&ephemeral_public_key_sender,
|
&ephemeral_public_key_sender,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -112,10 +110,10 @@ mod tests {
|
|||||||
let seed_holder = SeedHolder::new_os_random();
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
||||||
|
|
||||||
let utxo_secret_key_holder = top_secret_key_holder.produce_private_key_holder();
|
let utxo_secret_key_holder = top_secret_key_holder.produce_private_key_holder(None);
|
||||||
|
|
||||||
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
|
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
|
||||||
let viewing_public_key = utxo_secret_key_holder.generate_incoming_viewing_public_key();
|
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
|
||||||
|
|
||||||
let pub_account_signing_key = nssa::PrivateKey::new_os_random();
|
let pub_account_signing_key = nssa::PrivateKey::new_os_random();
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use bip39::Mnemonic;
|
|||||||
use common::HashType;
|
use common::HashType;
|
||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
NullifierPublicKey, NullifierSecretKey,
|
NullifierPublicKey, NullifierSecretKey,
|
||||||
encryption::{IncomingViewingPublicKey, Scalar},
|
encryption::{Scalar, ViewingPublicKey},
|
||||||
};
|
};
|
||||||
use rand::{RngCore, rngs::OsRng};
|
use rand::{RngCore, rngs::OsRng};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -18,20 +18,18 @@ pub struct SeedHolder {
|
|||||||
pub(crate) seed: Vec<u8>,
|
pub(crate) seed: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||||
/// Secret spending key object. Can produce `PrivateKeyHolder` objects.
|
/// Secret spending key object. Can produce `PrivateKeyHolder` objects.
|
||||||
pub struct SecretSpendingKey(pub(crate) [u8; 32]);
|
pub struct SecretSpendingKey(pub(crate) [u8; 32]);
|
||||||
|
|
||||||
pub type IncomingViewingSecretKey = Scalar;
|
pub type ViewingSecretKey = Scalar;
|
||||||
pub type OutgoingViewingSecretKey = Scalar;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
/// Private key holder. Produces public keys. Can produce account_id. Can produce shared secret for
|
/// Private key holder. Produces public keys. Can produce account_id. Can produce shared secret for
|
||||||
/// recepient.
|
/// recepient.
|
||||||
pub struct PrivateKeyHolder {
|
pub struct PrivateKeyHolder {
|
||||||
pub nullifier_secret_key: NullifierSecretKey,
|
pub nullifier_secret_key: NullifierSecretKey,
|
||||||
pub(crate) incoming_viewing_secret_key: IncomingViewingSecretKey,
|
pub(crate) viewing_secret_key: ViewingSecretKey,
|
||||||
pub outgoing_viewing_secret_key: OutgoingViewingSecretKey,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SeedHolder {
|
impl SeedHolder {
|
||||||
@ -75,44 +73,49 @@ impl SeedHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SecretSpendingKey {
|
impl SecretSpendingKey {
|
||||||
pub fn generate_nullifier_secret_key(&self) -> NullifierSecretKey {
|
pub fn generate_nullifier_secret_key(&self, index: Option<u32>) -> NullifierSecretKey {
|
||||||
let mut hasher = sha2::Sha256::new();
|
let index = match index {
|
||||||
|
None => 0u32,
|
||||||
|
_ => index.expect("Expect a valid u32"),
|
||||||
|
};
|
||||||
|
|
||||||
hasher.update("NSSA_keys");
|
const PREFIX: &[u8; 8] = b"LEE/keys";
|
||||||
|
const SUFFIX_1: &[u8; 1] = &[1];
|
||||||
|
const SUFFIX_2: &[u8; 19] = &[0; 19];
|
||||||
|
|
||||||
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
hasher.update(PREFIX);
|
||||||
hasher.update(self.0);
|
hasher.update(self.0);
|
||||||
hasher.update([1u8]);
|
hasher.update(SUFFIX_1);
|
||||||
hasher.update([0u8; 22]);
|
hasher.update(index.to_le_bytes());
|
||||||
|
hasher.update(SUFFIX_2);
|
||||||
|
|
||||||
<NullifierSecretKey>::from(hasher.finalize_fixed())
|
<NullifierSecretKey>::from(hasher.finalize_fixed())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_incoming_viewing_secret_key(&self) -> IncomingViewingSecretKey {
|
pub fn generate_viewing_secret_key(&self, index: Option<u32>) -> ViewingSecretKey {
|
||||||
let mut hasher = sha2::Sha256::new();
|
let index = match index {
|
||||||
|
None => 0u32,
|
||||||
|
_ => index.expect("Expect a valid u32"),
|
||||||
|
};
|
||||||
|
const PREFIX: &[u8; 8] = b"LEE/keys";
|
||||||
|
const SUFFIX_1: &[u8; 1] = &[2];
|
||||||
|
const SUFFIX_2: &[u8; 19] = &[0; 19];
|
||||||
|
|
||||||
hasher.update("NSSA_keys");
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
hasher.update(PREFIX);
|
||||||
hasher.update(self.0);
|
hasher.update(self.0);
|
||||||
hasher.update([2u8]);
|
hasher.update(SUFFIX_1);
|
||||||
hasher.update([0u8; 22]);
|
hasher.update(index.to_le_bytes());
|
||||||
|
hasher.update(SUFFIX_2);
|
||||||
|
|
||||||
hasher.finalize_fixed().into()
|
hasher.finalize_fixed().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_outgoing_viewing_secret_key(&self) -> OutgoingViewingSecretKey {
|
pub fn produce_private_key_holder(&self, index: Option<u32>) -> PrivateKeyHolder {
|
||||||
let mut hasher = sha2::Sha256::new();
|
|
||||||
|
|
||||||
hasher.update("NSSA_keys");
|
|
||||||
hasher.update(self.0);
|
|
||||||
hasher.update([3u8]);
|
|
||||||
hasher.update([0u8; 22]);
|
|
||||||
|
|
||||||
hasher.finalize_fixed().into()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn produce_private_key_holder(&self) -> PrivateKeyHolder {
|
|
||||||
PrivateKeyHolder {
|
PrivateKeyHolder {
|
||||||
nullifier_secret_key: self.generate_nullifier_secret_key(),
|
nullifier_secret_key: self.generate_nullifier_secret_key(index),
|
||||||
incoming_viewing_secret_key: self.generate_incoming_viewing_secret_key(),
|
viewing_secret_key: self.generate_viewing_secret_key(index),
|
||||||
outgoing_viewing_secret_key: self.generate_outgoing_viewing_secret_key(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,8 +125,8 @@ impl PrivateKeyHolder {
|
|||||||
(&self.nullifier_secret_key).into()
|
(&self.nullifier_secret_key).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_incoming_viewing_public_key(&self) -> IncomingViewingPublicKey {
|
pub fn generate_viewing_public_key(&self) -> ViewingPublicKey {
|
||||||
IncomingViewingPublicKey::from_scalar(self.incoming_viewing_secret_key)
|
ViewingPublicKey::from_scalar(self.viewing_secret_key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +134,7 @@ impl PrivateKeyHolder {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
// TODO? are these necessary?
|
||||||
#[test]
|
#[test]
|
||||||
fn seed_generation_test() {
|
fn seed_generation_test() {
|
||||||
let seed_holder = SeedHolder::new_os_random();
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
@ -155,18 +159,7 @@ mod tests {
|
|||||||
|
|
||||||
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
||||||
|
|
||||||
let _ = top_secret_key_holder.generate_incoming_viewing_secret_key();
|
let _ = top_secret_key_holder.generate_viewing_secret_key(None);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn ovs_generation_test() {
|
|
||||||
let seed_holder = SeedHolder::new_os_random();
|
|
||||||
|
|
||||||
assert_eq!(seed_holder.seed.len(), 64);
|
|
||||||
|
|
||||||
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
|
||||||
|
|
||||||
let _ = top_secret_key_holder.generate_outgoing_viewing_secret_key();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -33,3 +33,4 @@ test-case = "3.3.1"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
prove = ["risc0-zkvm/prove"]
|
||||||
|
|||||||
@ -159,6 +159,7 @@ mod tests {
|
|||||||
assert_eq!(new_acc_with_metadata.account_id, fingerprint);
|
assert_eq!(new_acc_with_metadata.account_id, fingerprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "host")]
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_valid_account_id() {
|
fn parse_valid_account_id() {
|
||||||
let base58_str = "11111111111111111111111111111111";
|
let base58_str = "11111111111111111111111111111111";
|
||||||
@ -166,6 +167,7 @@ mod tests {
|
|||||||
assert_eq!(account_id.value, [0u8; 32]);
|
assert_eq!(account_id.value, [0u8; 32]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "host")]
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_invalid_base58() {
|
fn parse_invalid_base58() {
|
||||||
let base58_str = "00".repeat(32); // invalid base58 chars
|
let base58_str = "00".repeat(32); // invalid base58 chars
|
||||||
@ -173,6 +175,7 @@ mod tests {
|
|||||||
assert!(matches!(result, AccountIdError::InvalidBase58(_)));
|
assert!(matches!(result, AccountIdError::InvalidBase58(_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "host")]
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_wrong_length_short() {
|
fn parse_wrong_length_short() {
|
||||||
let base58_str = "11".repeat(31); // 62 chars = 31 bytes
|
let base58_str = "11".repeat(31); // 62 chars = 31 bytes
|
||||||
@ -180,6 +183,7 @@ mod tests {
|
|||||||
assert!(matches!(result, AccountIdError::InvalidLength(_)));
|
assert!(matches!(result, AccountIdError::InvalidLength(_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "host")]
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_wrong_length_long() {
|
fn parse_wrong_length_long() {
|
||||||
let base58_str = "11".repeat(33); // 66 chars = 33 bytes
|
let base58_str = "11".repeat(33); // 66 chars = 33 bytes
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
pub mod shared_key_derivation;
|
pub mod shared_key_derivation;
|
||||||
|
|
||||||
#[cfg(feature = "host")]
|
#[cfg(feature = "host")]
|
||||||
pub use shared_key_derivation::{EphemeralPublicKey, EphemeralSecretKey, IncomingViewingPublicKey};
|
pub use shared_key_derivation::{EphemeralPublicKey, EphemeralSecretKey, ViewingPublicKey};
|
||||||
|
|
||||||
use crate::{Commitment, account::Account};
|
use crate::{Commitment, account::Account};
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ impl Secp256k1Point {
|
|||||||
|
|
||||||
pub type EphemeralSecretKey = Scalar;
|
pub type EphemeralSecretKey = Scalar;
|
||||||
pub type EphemeralPublicKey = Secp256k1Point;
|
pub type EphemeralPublicKey = Secp256k1Point;
|
||||||
pub type IncomingViewingPublicKey = Secp256k1Point;
|
pub type ViewingPublicKey = Secp256k1Point;
|
||||||
impl From<&EphemeralSecretKey> for EphemeralPublicKey {
|
impl From<&EphemeralSecretKey> for EphemeralPublicKey {
|
||||||
fn from(value: &EphemeralSecretKey) -> Self {
|
fn from(value: &EphemeralSecretKey) -> Self {
|
||||||
Secp256k1Point::from_scalar(*value)
|
Secp256k1Point::from_scalar(*value)
|
||||||
|
|||||||
@ -10,7 +10,8 @@ pub struct NullifierPublicKey(pub [u8; 32]);
|
|||||||
|
|
||||||
impl From<&NullifierPublicKey> for AccountId {
|
impl From<&NullifierPublicKey> for AccountId {
|
||||||
fn from(value: &NullifierPublicKey) -> Self {
|
fn from(value: &NullifierPublicKey) -> Self {
|
||||||
const PRIVATE_ACCOUNT_ID_PREFIX: &[u8; 32] = b"/NSSA/v0.2/AccountId/Private/\x00\x00\x00";
|
const PRIVATE_ACCOUNT_ID_PREFIX: &[u8; 32] =
|
||||||
|
b"/LEE/v0.3/AccountId/Private/\x00\x00\x00\x00";
|
||||||
|
|
||||||
let mut bytes = [0; 64];
|
let mut bytes = [0; 64];
|
||||||
bytes[0..32].copy_from_slice(PRIVATE_ACCOUNT_ID_PREFIX);
|
bytes[0..32].copy_from_slice(PRIVATE_ACCOUNT_ID_PREFIX);
|
||||||
@ -28,9 +29,9 @@ impl AsRef<[u8]> for NullifierPublicKey {
|
|||||||
impl From<&NullifierSecretKey> for NullifierPublicKey {
|
impl From<&NullifierSecretKey> for NullifierPublicKey {
|
||||||
fn from(value: &NullifierSecretKey) -> Self {
|
fn from(value: &NullifierSecretKey) -> Self {
|
||||||
let mut bytes = Vec::new();
|
let mut bytes = Vec::new();
|
||||||
const PREFIX: &[u8; 9] = b"NSSA_keys";
|
const PREFIX: &[u8; 8] = b"LEE/keys";
|
||||||
const SUFFIX_1: &[u8; 1] = &[7];
|
const SUFFIX_1: &[u8; 1] = &[7];
|
||||||
const SUFFIX_2: &[u8; 22] = &[0; 22];
|
const SUFFIX_2: &[u8; 23] = &[0; 23];
|
||||||
bytes.extend_from_slice(PREFIX);
|
bytes.extend_from_slice(PREFIX);
|
||||||
bytes.extend_from_slice(value);
|
bytes.extend_from_slice(value);
|
||||||
bytes.extend_from_slice(SUFFIX_1);
|
bytes.extend_from_slice(SUFFIX_1);
|
||||||
@ -102,8 +103,8 @@ mod tests {
|
|||||||
196, 134, 22, 224, 211, 237, 120, 136, 225, 188, 220, 249, 28,
|
196, 134, 22, 224, 211, 237, 120, 136, 225, 188, 220, 249, 28,
|
||||||
];
|
];
|
||||||
let expected_npk = NullifierPublicKey([
|
let expected_npk = NullifierPublicKey([
|
||||||
202, 120, 42, 189, 194, 218, 78, 244, 31, 6, 108, 169, 29, 61, 22, 221, 69, 138, 197,
|
78, 20, 20, 5, 177, 198, 233, 100, 175, 134, 174, 200, 24, 205, 68, 215, 130, 74, 35,
|
||||||
161, 241, 39, 142, 242, 242, 50, 188, 201, 99, 28, 176, 238,
|
54, 154, 184, 219, 42, 168, 106, 126, 147, 133, 244, 18, 218,
|
||||||
]);
|
]);
|
||||||
let npk = NullifierPublicKey::from(&nsk);
|
let npk = NullifierPublicKey::from(&nsk);
|
||||||
assert_eq!(npk, expected_npk);
|
assert_eq!(npk, expected_npk);
|
||||||
@ -117,8 +118,8 @@ mod tests {
|
|||||||
];
|
];
|
||||||
let npk = NullifierPublicKey::from(&nsk);
|
let npk = NullifierPublicKey::from(&nsk);
|
||||||
let expected_account_id = AccountId::new([
|
let expected_account_id = AccountId::new([
|
||||||
18, 153, 225, 78, 35, 214, 212, 205, 152, 83, 18, 246, 69, 41, 20, 217, 85, 1, 108, 7,
|
139, 72, 194, 222, 215, 187, 147, 56, 55, 35, 222, 205, 156, 12, 204, 227, 166, 44, 30,
|
||||||
87, 133, 181, 53, 247, 221, 174, 12, 112, 194, 34, 121,
|
81, 186, 14, 167, 234, 28, 236, 32, 213, 125, 251, 193, 233,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let account_id = AccountId::from(&npk);
|
let account_id = AccountId::from(&npk);
|
||||||
|
|||||||
@ -223,7 +223,7 @@ mod tests {
|
|||||||
let expected_sender_pre = sender.clone();
|
let expected_sender_pre = sender.clone();
|
||||||
|
|
||||||
let esk = [3; 32];
|
let esk = [3; 32];
|
||||||
let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.ivk());
|
let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.vpk());
|
||||||
|
|
||||||
let (output, proof) = execute_and_prove(
|
let (output, proof) = execute_and_prove(
|
||||||
vec![sender, recipient],
|
vec![sender, recipient],
|
||||||
@ -316,10 +316,10 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let esk_1 = [3; 32];
|
let esk_1 = [3; 32];
|
||||||
let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_keys.ivk());
|
let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_keys.vpk());
|
||||||
|
|
||||||
let esk_2 = [5; 32];
|
let esk_2 = [5; 32];
|
||||||
let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.ivk());
|
let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.vpk());
|
||||||
|
|
||||||
let (output, proof) = execute_and_prove(
|
let (output, proof) = execute_and_prove(
|
||||||
vec![sender_pre.clone(), recipient],
|
vec![sender_pre.clone(), recipient],
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use borsh::{BorshDeserialize, BorshSerialize};
|
|||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
Commitment, CommitmentSetDigest, Nullifier, NullifierPublicKey, PrivacyPreservingCircuitOutput,
|
Commitment, CommitmentSetDigest, Nullifier, NullifierPublicKey, PrivacyPreservingCircuitOutput,
|
||||||
account::{Account, Nonce},
|
account::{Account, Nonce},
|
||||||
encryption::{Ciphertext, EphemeralPublicKey, IncomingViewingPublicKey},
|
encryption::{Ciphertext, EphemeralPublicKey, ViewingPublicKey},
|
||||||
};
|
};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
@ -21,10 +21,10 @@ impl EncryptedAccountData {
|
|||||||
fn new(
|
fn new(
|
||||||
ciphertext: Ciphertext,
|
ciphertext: Ciphertext,
|
||||||
npk: NullifierPublicKey,
|
npk: NullifierPublicKey,
|
||||||
ivk: IncomingViewingPublicKey,
|
vpk: ViewingPublicKey,
|
||||||
epk: EphemeralPublicKey,
|
epk: EphemeralPublicKey,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let view_tag = Self::compute_view_tag(npk, ivk);
|
let view_tag = Self::compute_view_tag(npk, vpk);
|
||||||
Self {
|
Self {
|
||||||
ciphertext,
|
ciphertext,
|
||||||
epk,
|
epk,
|
||||||
@ -32,12 +32,12 @@ impl EncryptedAccountData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the tag as the first byte of SHA256("/NSSA/v0.2/ViewTag/" || Npk || Ivk)
|
/// Computes the tag as the first byte of SHA256("/NSSA/v0.2/ViewTag/" || Npk || vpk)
|
||||||
pub fn compute_view_tag(npk: NullifierPublicKey, ivk: IncomingViewingPublicKey) -> ViewTag {
|
pub fn compute_view_tag(npk: NullifierPublicKey, vpk: ViewingPublicKey) -> ViewTag {
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
hasher.update(b"/NSSA/v0.2/ViewTag/");
|
hasher.update(b"/NSSA/v0.2/ViewTag/");
|
||||||
hasher.update(npk.to_byte_array());
|
hasher.update(npk.to_byte_array());
|
||||||
hasher.update(ivk.to_bytes());
|
hasher.update(vpk.to_bytes());
|
||||||
let digest: [u8; 32] = hasher.finalize().into();
|
let digest: [u8; 32] = hasher.finalize().into();
|
||||||
digest[0]
|
digest[0]
|
||||||
}
|
}
|
||||||
@ -57,11 +57,7 @@ impl Message {
|
|||||||
pub fn try_from_circuit_output(
|
pub fn try_from_circuit_output(
|
||||||
public_account_ids: Vec<AccountId>,
|
public_account_ids: Vec<AccountId>,
|
||||||
nonces: Vec<Nonce>,
|
nonces: Vec<Nonce>,
|
||||||
public_keys: Vec<(
|
public_keys: Vec<(NullifierPublicKey, ViewingPublicKey, EphemeralPublicKey)>,
|
||||||
NullifierPublicKey,
|
|
||||||
IncomingViewingPublicKey,
|
|
||||||
EphemeralPublicKey,
|
|
||||||
)>,
|
|
||||||
output: PrivacyPreservingCircuitOutput,
|
output: PrivacyPreservingCircuitOutput,
|
||||||
) -> Result<Self, NssaError> {
|
) -> Result<Self, NssaError> {
|
||||||
if public_keys.len() != output.ciphertexts.len() {
|
if public_keys.len() != output.ciphertexts.len() {
|
||||||
@ -74,8 +70,8 @@ impl Message {
|
|||||||
.ciphertexts
|
.ciphertexts
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(public_keys)
|
.zip(public_keys)
|
||||||
.map(|(ciphertext, (npk, ivk, epk))| {
|
.map(|(ciphertext, (npk, vpk, epk))| {
|
||||||
EncryptedAccountData::new(ciphertext, npk, ivk, epk)
|
EncryptedAccountData::new(ciphertext, npk, vpk, epk)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -94,7 +90,7 @@ pub mod tests {
|
|||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
Commitment, EncryptionScheme, Nullifier, NullifierPublicKey, SharedSecretKey,
|
Commitment, EncryptionScheme, Nullifier, NullifierPublicKey, SharedSecretKey,
|
||||||
account::Account,
|
account::Account,
|
||||||
encryption::{EphemeralPublicKey, IncomingViewingPublicKey},
|
encryption::{EphemeralPublicKey, ViewingPublicKey},
|
||||||
};
|
};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
@ -142,21 +138,21 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_encrypted_account_data_constructor() {
|
fn test_encrypted_account_data_constructor() {
|
||||||
let npk = NullifierPublicKey::from(&[1; 32]);
|
let npk = NullifierPublicKey::from(&[1; 32]);
|
||||||
let ivk = IncomingViewingPublicKey::from_scalar([2; 32]);
|
let vpk = ViewingPublicKey::from_scalar([2; 32]);
|
||||||
let account = Account::default();
|
let account = Account::default();
|
||||||
let commitment = Commitment::new(&npk, &account);
|
let commitment = Commitment::new(&npk, &account);
|
||||||
let esk = [3; 32];
|
let esk = [3; 32];
|
||||||
let shared_secret = SharedSecretKey::new(&esk, &ivk);
|
let shared_secret = SharedSecretKey::new(&esk, &vpk);
|
||||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||||
let ciphertext = EncryptionScheme::encrypt(&account, &shared_secret, &commitment, 2);
|
let ciphertext = EncryptionScheme::encrypt(&account, &shared_secret, &commitment, 2);
|
||||||
let encrypted_account_data =
|
let encrypted_account_data =
|
||||||
EncryptedAccountData::new(ciphertext.clone(), npk.clone(), ivk.clone(), epk.clone());
|
EncryptedAccountData::new(ciphertext.clone(), npk.clone(), vpk.clone(), epk.clone());
|
||||||
|
|
||||||
let expected_view_tag = {
|
let expected_view_tag = {
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
hasher.update(b"/NSSA/v0.2/ViewTag/");
|
hasher.update(b"/NSSA/v0.2/ViewTag/");
|
||||||
hasher.update(npk.to_byte_array());
|
hasher.update(npk.to_byte_array());
|
||||||
hasher.update(ivk.to_bytes());
|
hasher.update(vpk.to_bytes());
|
||||||
let digest: [u8; 32] = hasher.finalize().into();
|
let digest: [u8; 32] = hasher.finalize().into();
|
||||||
digest[0]
|
digest[0]
|
||||||
};
|
};
|
||||||
@ -165,7 +161,7 @@ pub mod tests {
|
|||||||
assert_eq!(encrypted_account_data.epk, epk);
|
assert_eq!(encrypted_account_data.epk, epk);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
encrypted_account_data.view_tag,
|
encrypted_account_data.view_tag,
|
||||||
EncryptedAccountData::compute_view_tag(npk, ivk)
|
EncryptedAccountData::compute_view_tag(npk, vpk)
|
||||||
);
|
);
|
||||||
assert_eq!(encrypted_account_data.view_tag, expected_view_tag);
|
assert_eq!(encrypted_account_data.view_tag, expected_view_tag);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -315,7 +315,7 @@ pub mod tests {
|
|||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
Commitment, Nullifier, NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
|
Commitment, Nullifier, NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
|
||||||
account::{Account, AccountId, AccountWithMetadata, Nonce, data::Data},
|
account::{Account, AccountId, AccountWithMetadata, Nonce, data::Data},
|
||||||
encryption::{EphemeralPublicKey, IncomingViewingPublicKey, Scalar},
|
encryption::{EphemeralPublicKey, Scalar, ViewingPublicKey},
|
||||||
program::{PdaSeed, ProgramId},
|
program::{PdaSeed, ProgramId},
|
||||||
};
|
};
|
||||||
use token_core::{TokenDefinition, TokenHolding};
|
use token_core::{TokenDefinition, TokenHolding};
|
||||||
@ -864,7 +864,7 @@ pub mod tests {
|
|||||||
|
|
||||||
pub struct TestPrivateKeys {
|
pub struct TestPrivateKeys {
|
||||||
pub nsk: NullifierSecretKey,
|
pub nsk: NullifierSecretKey,
|
||||||
pub isk: Scalar,
|
pub vsk: Scalar,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestPrivateKeys {
|
impl TestPrivateKeys {
|
||||||
@ -872,22 +872,22 @@ pub mod tests {
|
|||||||
NullifierPublicKey::from(&self.nsk)
|
NullifierPublicKey::from(&self.nsk)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ivk(&self) -> IncomingViewingPublicKey {
|
pub fn vpk(&self) -> ViewingPublicKey {
|
||||||
IncomingViewingPublicKey::from_scalar(self.isk)
|
ViewingPublicKey::from_scalar(self.vsk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_private_account_keys_1() -> TestPrivateKeys {
|
pub fn test_private_account_keys_1() -> TestPrivateKeys {
|
||||||
TestPrivateKeys {
|
TestPrivateKeys {
|
||||||
nsk: [13; 32],
|
nsk: [13; 32],
|
||||||
isk: [31; 32],
|
vsk: [31; 32],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_private_account_keys_2() -> TestPrivateKeys {
|
pub fn test_private_account_keys_2() -> TestPrivateKeys {
|
||||||
TestPrivateKeys {
|
TestPrivateKeys {
|
||||||
nsk: [38; 32],
|
nsk: [38; 32],
|
||||||
isk: [83; 32],
|
vsk: [83; 32],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,7 +908,7 @@ pub mod tests {
|
|||||||
let recipient = AccountWithMetadata::new(Account::default(), false, &recipient_keys.npk());
|
let recipient = AccountWithMetadata::new(Account::default(), false, &recipient_keys.npk());
|
||||||
|
|
||||||
let esk = [3; 32];
|
let esk = [3; 32];
|
||||||
let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.ivk());
|
let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.vpk());
|
||||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
@ -926,7 +926,7 @@ pub mod tests {
|
|||||||
let message = Message::try_from_circuit_output(
|
let message = Message::try_from_circuit_output(
|
||||||
vec![sender_keys.account_id()],
|
vec![sender_keys.account_id()],
|
||||||
vec![sender_nonce],
|
vec![sender_nonce],
|
||||||
vec![(recipient_keys.npk(), recipient_keys.ivk(), epk)],
|
vec![(recipient_keys.npk(), recipient_keys.vpk(), epk)],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -951,11 +951,11 @@ pub mod tests {
|
|||||||
AccountWithMetadata::new(Account::default(), false, &recipient_keys.npk());
|
AccountWithMetadata::new(Account::default(), false, &recipient_keys.npk());
|
||||||
|
|
||||||
let esk_1 = [3; 32];
|
let esk_1 = [3; 32];
|
||||||
let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_keys.ivk());
|
let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_keys.vpk());
|
||||||
let epk_1 = EphemeralPublicKey::from_scalar(esk_1);
|
let epk_1 = EphemeralPublicKey::from_scalar(esk_1);
|
||||||
|
|
||||||
let esk_2 = [3; 32];
|
let esk_2 = [3; 32];
|
||||||
let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.ivk());
|
let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.vpk());
|
||||||
let epk_2 = EphemeralPublicKey::from_scalar(esk_2);
|
let epk_2 = EphemeralPublicKey::from_scalar(esk_2);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
@ -977,8 +977,8 @@ pub mod tests {
|
|||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
vec![
|
vec![
|
||||||
(sender_keys.npk(), sender_keys.ivk(), epk_1),
|
(sender_keys.npk(), sender_keys.vpk(), epk_1),
|
||||||
(recipient_keys.npk(), recipient_keys.ivk(), epk_2),
|
(recipient_keys.npk(), recipient_keys.vpk(), epk_2),
|
||||||
],
|
],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
@ -1008,7 +1008,7 @@ pub mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let esk = [3; 32];
|
let esk = [3; 32];
|
||||||
let shared_secret = SharedSecretKey::new(&esk, &sender_keys.ivk());
|
let shared_secret = SharedSecretKey::new(&esk, &sender_keys.vpk());
|
||||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
@ -1026,7 +1026,7 @@ pub mod tests {
|
|||||||
let message = Message::try_from_circuit_output(
|
let message = Message::try_from_circuit_output(
|
||||||
vec![*recipient_account_id],
|
vec![*recipient_account_id],
|
||||||
vec![],
|
vec![],
|
||||||
vec![(sender_keys.npk(), sender_keys.ivk(), epk)],
|
vec![(sender_keys.npk(), sender_keys.vpk(), epk)],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1538,11 +1538,11 @@ pub mod tests {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
vec![sender_keys.nsk],
|
vec![sender_keys.nsk],
|
||||||
@ -1572,7 +1572,7 @@ pub mod tests {
|
|||||||
// Setting only one key for an execution with two private accounts.
|
// Setting only one key for an execution with two private accounts.
|
||||||
let private_account_keys = [(
|
let private_account_keys = [(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
)];
|
)];
|
||||||
let result = execute_and_prove(
|
let result = execute_and_prove(
|
||||||
vec![private_account_1, private_account_2],
|
vec![private_account_1, private_account_2],
|
||||||
@ -1615,11 +1615,11 @@ pub mod tests {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
vec![sender_keys.nsk],
|
vec![sender_keys.nsk],
|
||||||
@ -1657,11 +1657,11 @@ pub mod tests {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
private_account_nsks.to_vec(),
|
private_account_nsks.to_vec(),
|
||||||
@ -1693,12 +1693,12 @@ pub mod tests {
|
|||||||
// First private account is the sender
|
// First private account is the sender
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
// Second private account is the recipient
|
// Second private account is the recipient
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -1753,11 +1753,11 @@ pub mod tests {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
vec![sender_keys.nsk],
|
vec![sender_keys.nsk],
|
||||||
@ -1801,11 +1801,11 @@ pub mod tests {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
vec![sender_keys.nsk],
|
vec![sender_keys.nsk],
|
||||||
@ -1848,11 +1848,11 @@ pub mod tests {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
vec![sender_keys.nsk],
|
vec![sender_keys.nsk],
|
||||||
@ -1895,11 +1895,11 @@ pub mod tests {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
vec![sender_keys.nsk],
|
vec![sender_keys.nsk],
|
||||||
@ -1940,11 +1940,11 @@ pub mod tests {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
vec![sender_keys.nsk],
|
vec![sender_keys.nsk],
|
||||||
@ -2013,11 +2013,11 @@ pub mod tests {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
vec![sender_keys.nsk],
|
vec![sender_keys.nsk],
|
||||||
@ -2050,15 +2050,15 @@ pub mod tests {
|
|||||||
let private_account_keys = [
|
let private_account_keys = [
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[57; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[57; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
let result = execute_and_prove(
|
let result = execute_and_prove(
|
||||||
@ -2105,11 +2105,11 @@ pub mod tests {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
recipient_keys.npk(),
|
recipient_keys.npk(),
|
||||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
private_account_nsks.to_vec(),
|
private_account_nsks.to_vec(),
|
||||||
@ -2192,7 +2192,7 @@ pub mod tests {
|
|||||||
let visibility_mask = [1, 1];
|
let visibility_mask = [1, 1];
|
||||||
let private_account_nsks = [sender_keys.nsk, sender_keys.nsk];
|
let private_account_nsks = [sender_keys.nsk, sender_keys.nsk];
|
||||||
let private_account_membership_proofs = [Some((1, vec![])), Some((1, vec![]))];
|
let private_account_membership_proofs = [Some((1, vec![])), Some((1, vec![]))];
|
||||||
let shared_secret = SharedSecretKey::new(&[55; 32], &sender_keys.ivk());
|
let shared_secret = SharedSecretKey::new(&[55; 32], &sender_keys.vpk());
|
||||||
let result = execute_and_prove(
|
let result = execute_and_prove(
|
||||||
vec![private_account_1.clone(), private_account_1],
|
vec![private_account_1.clone(), private_account_1],
|
||||||
Program::serialize_instruction(100u128).unwrap(),
|
Program::serialize_instruction(100u128).unwrap(),
|
||||||
@ -3809,11 +3809,11 @@ pub mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let from_esk = [3; 32];
|
let from_esk = [3; 32];
|
||||||
let from_ss = SharedSecretKey::new(&from_esk, &from_keys.ivk());
|
let from_ss = SharedSecretKey::new(&from_esk, &from_keys.vpk());
|
||||||
let from_epk = EphemeralPublicKey::from_scalar(from_esk);
|
let from_epk = EphemeralPublicKey::from_scalar(from_esk);
|
||||||
|
|
||||||
let to_esk = [3; 32];
|
let to_esk = [3; 32];
|
||||||
let to_ss = SharedSecretKey::new(&to_esk, &to_keys.ivk());
|
let to_ss = SharedSecretKey::new(&to_esk, &to_keys.vpk());
|
||||||
let to_epk = EphemeralPublicKey::from_scalar(to_esk);
|
let to_epk = EphemeralPublicKey::from_scalar(to_esk);
|
||||||
|
|
||||||
let mut dependencies = HashMap::new();
|
let mut dependencies = HashMap::new();
|
||||||
@ -3858,8 +3858,8 @@ pub mod tests {
|
|||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
vec![
|
vec![
|
||||||
(to_keys.npk(), to_keys.ivk(), to_epk),
|
(to_keys.npk(), to_keys.vpk(), to_epk),
|
||||||
(from_keys.npk(), from_keys.ivk(), from_epk),
|
(from_keys.npk(), from_keys.vpk(), from_epk),
|
||||||
],
|
],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
@ -4069,7 +4069,7 @@ pub mod tests {
|
|||||||
|
|
||||||
// Set up parameters for the new account
|
// Set up parameters for the new account
|
||||||
let esk = [3; 32];
|
let esk = [3; 32];
|
||||||
let shared_secret = SharedSecretKey::new(&esk, &private_keys.ivk());
|
let shared_secret = SharedSecretKey::new(&esk, &private_keys.vpk());
|
||||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||||
|
|
||||||
// Balance to initialize the account with (0 for a new account)
|
// Balance to initialize the account with (0 for a new account)
|
||||||
@ -4094,7 +4094,7 @@ pub mod tests {
|
|||||||
let message = Message::try_from_circuit_output(
|
let message = Message::try_from_circuit_output(
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
vec![(private_keys.npk(), private_keys.ivk(), epk)],
|
vec![(private_keys.npk(), private_keys.vpk(), epk)],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -4124,7 +4124,7 @@ pub mod tests {
|
|||||||
|
|
||||||
// Set up parameters for claiming the new account
|
// Set up parameters for claiming the new account
|
||||||
let esk = [3; 32];
|
let esk = [3; 32];
|
||||||
let shared_secret = SharedSecretKey::new(&esk, &private_keys.ivk());
|
let shared_secret = SharedSecretKey::new(&esk, &private_keys.vpk());
|
||||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||||
|
|
||||||
let balance: u128 = 0;
|
let balance: u128 = 0;
|
||||||
@ -4146,7 +4146,7 @@ pub mod tests {
|
|||||||
let message = Message::try_from_circuit_output(
|
let message = Message::try_from_circuit_output(
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
vec![(private_keys.npk(), private_keys.ivk(), epk)],
|
vec![(private_keys.npk(), private_keys.vpk(), epk)],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -4174,7 +4174,7 @@ pub mod tests {
|
|||||||
|
|
||||||
let noop_program = Program::noop();
|
let noop_program = Program::noop();
|
||||||
let esk2 = [4; 32];
|
let esk2 = [4; 32];
|
||||||
let shared_secret2 = SharedSecretKey::new(&esk2, &private_keys.ivk());
|
let shared_secret2 = SharedSecretKey::new(&esk2, &private_keys.vpk());
|
||||||
|
|
||||||
let nonce2 = 0xdeadbeef2;
|
let nonce2 = 0xdeadbeef2;
|
||||||
|
|
||||||
@ -4256,7 +4256,7 @@ pub mod tests {
|
|||||||
vec![2],
|
vec![2],
|
||||||
vec![(
|
vec![(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[3; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[3; 32], &sender_keys.vpk()),
|
||||||
)],
|
)],
|
||||||
vec![sender_keys.nsk],
|
vec![sender_keys.nsk],
|
||||||
vec![Some((0, vec![]))],
|
vec![Some((0, vec![]))],
|
||||||
@ -4284,7 +4284,7 @@ pub mod tests {
|
|||||||
vec![2],
|
vec![2],
|
||||||
vec![(
|
vec![(
|
||||||
sender_keys.npk(),
|
sender_keys.npk(),
|
||||||
SharedSecretKey::new(&[3; 32], &sender_keys.ivk()),
|
SharedSecretKey::new(&[3; 32], &sender_keys.vpk()),
|
||||||
)],
|
)],
|
||||||
vec![sender_keys.nsk],
|
vec![sender_keys.nsk],
|
||||||
vec![Some((0, vec![]))],
|
vec![Some((0, vec![]))],
|
||||||
@ -4327,7 +4327,7 @@ pub mod tests {
|
|||||||
let instruction = (balance_to_transfer, auth_transfers.id());
|
let instruction = (balance_to_transfer, auth_transfers.id());
|
||||||
|
|
||||||
let recipient_esk = [3; 32];
|
let recipient_esk = [3; 32];
|
||||||
let recipient = SharedSecretKey::new(&recipient_esk, &recipient_keys.ivk());
|
let recipient = SharedSecretKey::new(&recipient_esk, &recipient_keys.vpk());
|
||||||
|
|
||||||
let mut dependencies = HashMap::new();
|
let mut dependencies = HashMap::new();
|
||||||
dependencies.insert(auth_transfers.id(), auth_transfers);
|
dependencies.insert(auth_transfers.id(), auth_transfers);
|
||||||
|
|||||||
@ -118,7 +118,7 @@ pub fn add_liquidity(
|
|||||||
assert!(delta_lp != 0, "Payable LP must be nonzero");
|
assert!(delta_lp != 0, "Payable LP must be nonzero");
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
delta_lp >= min_amount_liquidity.into(),
|
delta_lp >= min_amount_liquidity.get(),
|
||||||
"Payable LP is less than provided minimum LP amount"
|
"Payable LP is less than provided minimum LP amount"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -927,15 +927,15 @@ mod tests {
|
|||||||
|
|
||||||
fn acc1() -> AccountId {
|
fn acc1() -> AccountId {
|
||||||
AccountId::new([
|
AccountId::new([
|
||||||
208, 122, 210, 232, 75, 39, 250, 0, 194, 98, 240, 161, 238, 160, 255, 53, 202, 9, 115,
|
148, 179, 206, 253, 199, 51, 82, 86, 232, 2, 152, 122, 80, 243, 54, 207, 237, 112, 83,
|
||||||
84, 126, 106, 16, 111, 114, 241, 147, 194, 220, 131, 139, 68,
|
153, 44, 59, 204, 49, 128, 84, 160, 227, 216, 149, 97, 102,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn acc2() -> AccountId {
|
fn acc2() -> AccountId {
|
||||||
AccountId::new([
|
AccountId::new([
|
||||||
231, 174, 119, 197, 239, 26, 5, 153, 147, 68, 175, 73, 159, 199, 138, 23, 5, 57, 141,
|
30, 145, 107, 3, 207, 73, 192, 230, 160, 63, 238, 207, 18, 69, 54, 216, 103, 244, 92,
|
||||||
98, 237, 6, 207, 46, 20, 121, 246, 222, 248, 154, 57, 188,
|
94, 124, 248, 42, 16, 141, 19, 119, 18, 14, 226, 140, 204,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,3 +19,7 @@ cbindgen = "0.29"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
prove = ["nssa/prove"]
|
||||||
|
|||||||
@ -354,6 +354,61 @@ pub unsafe extern "C" fn wallet_ffi_get_account_public(
|
|||||||
WalletFfiError::Success
|
WalletFfiError::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get full private account data from the local storage.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
/// - `handle`: Valid wallet handle
|
||||||
|
/// - `account_id`: The account ID (32 bytes)
|
||||||
|
/// - `out_account`: Output pointer for account data
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// - `Success` on successful query
|
||||||
|
/// - Error code on failure
|
||||||
|
///
|
||||||
|
/// # Memory
|
||||||
|
/// The account data must be freed with `wallet_ffi_free_account_data()`.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||||
|
/// - `account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
/// - `out_account` must be a valid pointer to a `FfiAccount` struct
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wallet_ffi_get_account_private(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
account_id: *const FfiBytes32,
|
||||||
|
out_account: *mut FfiAccount,
|
||||||
|
) -> WalletFfiError {
|
||||||
|
let wrapper = match get_wallet(handle) {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => return e,
|
||||||
|
};
|
||||||
|
|
||||||
|
if account_id.is_null() || out_account.is_null() {
|
||||||
|
print_error("Null pointer argument");
|
||||||
|
return WalletFfiError::NullPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
let wallet = match wrapper.core.lock() {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!("Failed to lock wallet: {}", e));
|
||||||
|
return WalletFfiError::InternalError;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let account_id = AccountId::new(unsafe { (*account_id).data });
|
||||||
|
|
||||||
|
let Some(account) = wallet.get_account_private(account_id) else {
|
||||||
|
return WalletFfiError::AccountNotFound;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
*out_account = account.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletFfiError::Success
|
||||||
|
}
|
||||||
|
|
||||||
/// Free account data returned by `wallet_ffi_get_account_public`.
|
/// Free account data returned by `wallet_ffi_get_account_public`.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
|||||||
@ -73,7 +73,7 @@ pub unsafe extern "C" fn wallet_ffi_get_public_account_key(
|
|||||||
|
|
||||||
/// Get keys for a private account.
|
/// Get keys for a private account.
|
||||||
///
|
///
|
||||||
/// Returns the nullifier public key (NPK) and incoming viewing public key (IPK)
|
/// Returns the nullifier public key (NPK) and viewing public key (VPK)
|
||||||
/// for the specified private account. These keys are safe to share publicly.
|
/// for the specified private account. These keys are safe to share publicly.
|
||||||
///
|
///
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
@ -130,17 +130,17 @@ pub unsafe extern "C" fn wallet_ffi_get_private_account_keys(
|
|||||||
// NPK is a 32-byte array
|
// NPK is a 32-byte array
|
||||||
let npk_bytes = key_chain.nullifer_public_key.0;
|
let npk_bytes = key_chain.nullifer_public_key.0;
|
||||||
|
|
||||||
// IPK is a compressed secp256k1 point (33 bytes)
|
// VPK is a compressed secp256k1 point (33 bytes)
|
||||||
let ipk_bytes = key_chain.incoming_viewing_public_key.to_bytes();
|
let vpk_bytes = key_chain.viewing_public_key.to_bytes();
|
||||||
let ipk_len = ipk_bytes.len();
|
let vpk_len = vpk_bytes.len();
|
||||||
let ipk_vec = ipk_bytes.to_vec();
|
let vpk_vec = vpk_bytes.to_vec();
|
||||||
let ipk_boxed = ipk_vec.into_boxed_slice();
|
let vpk_boxed = vpk_vec.into_boxed_slice();
|
||||||
let ipk_ptr = Box::into_raw(ipk_boxed) as *const u8;
|
let vpk_ptr = Box::into_raw(vpk_boxed) as *const u8;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
(*out_keys).nullifier_public_key.data = npk_bytes;
|
(*out_keys).nullifier_public_key.data = npk_bytes;
|
||||||
(*out_keys).incoming_viewing_public_key = ipk_ptr;
|
(*out_keys).viewing_public_key = vpk_ptr;
|
||||||
(*out_keys).incoming_viewing_public_key_len = ipk_len;
|
(*out_keys).viewing_public_key_len = vpk_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletFfiError::Success
|
WalletFfiError::Success
|
||||||
@ -159,10 +159,10 @@ pub unsafe extern "C" fn wallet_ffi_free_private_account_keys(keys: *mut FfiPriv
|
|||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let keys = &*keys;
|
let keys = &*keys;
|
||||||
if !keys.incoming_viewing_public_key.is_null() && keys.incoming_viewing_public_key_len > 0 {
|
if !keys.viewing_public_key.is_null() && keys.viewing_public_key_len > 0 {
|
||||||
let slice = std::slice::from_raw_parts_mut(
|
let slice = std::slice::from_raw_parts_mut(
|
||||||
keys.incoming_viewing_public_key as *mut u8,
|
keys.viewing_public_key as *mut u8,
|
||||||
keys.incoming_viewing_public_key_len,
|
keys.viewing_public_key_len,
|
||||||
);
|
);
|
||||||
drop(Box::from_raw(slice as *mut [u8]));
|
drop(Box::from_raw(slice as *mut [u8]));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ use crate::{
|
|||||||
error::{print_error, WalletFfiError},
|
error::{print_error, WalletFfiError},
|
||||||
types::{FfiBytes32, FfiTransferResult, WalletHandle},
|
types::{FfiBytes32, FfiTransferResult, WalletHandle},
|
||||||
wallet::get_wallet,
|
wallet::get_wallet,
|
||||||
|
FfiPrivateAccountKeys,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Send a public token transfer.
|
/// Send a public token transfer.
|
||||||
@ -89,13 +90,270 @@ pub unsafe extern "C" fn wallet_ffi_transfer_public(
|
|||||||
(*out_result).tx_hash = ptr::null_mut();
|
(*out_result).tx_hash = ptr::null_mut();
|
||||||
(*out_result).success = false;
|
(*out_result).success = false;
|
||||||
}
|
}
|
||||||
match e {
|
map_execution_error(e)
|
||||||
ExecutionFailureKind::InsufficientFundsError => WalletFfiError::InsufficientFunds,
|
}
|
||||||
ExecutionFailureKind::KeyNotFoundError => WalletFfiError::KeyNotFound,
|
Err(e) => e,
|
||||||
ExecutionFailureKind::SequencerError => WalletFfiError::NetworkError,
|
}
|
||||||
ExecutionFailureKind::SequencerClientError(_) => WalletFfiError::NetworkError,
|
}
|
||||||
_ => WalletFfiError::InternalError,
|
|
||||||
|
/// Send a shielded token transfer.
|
||||||
|
///
|
||||||
|
/// Transfers tokens from a public account to a private account.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
/// - `handle`: Valid wallet handle
|
||||||
|
/// - `from`: Source account ID (must be owned by this wallet)
|
||||||
|
/// - `to_keys`: Destination account keys
|
||||||
|
/// - `amount`: Amount to transfer as little-endian [u8; 16]
|
||||||
|
/// - `out_result`: Output pointer for transfer result
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// - `Success` if the transfer was submitted successfully
|
||||||
|
/// - `InsufficientFunds` if the source account doesn't have enough balance
|
||||||
|
/// - `KeyNotFound` if the source account's signing key is not in this wallet
|
||||||
|
/// - Error code on other failures
|
||||||
|
///
|
||||||
|
/// # Memory
|
||||||
|
/// The result must be freed with `wallet_ffi_free_transfer_result()`.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||||
|
/// - `from` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
/// - `to_keys` must be a valid pointer to a `FfiPrivateAccountKeys` struct
|
||||||
|
/// - `amount` must be a valid pointer to a `[u8; 16]` array
|
||||||
|
/// - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wallet_ffi_transfer_shielded(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
from: *const FfiBytes32,
|
||||||
|
to_keys: *const FfiPrivateAccountKeys,
|
||||||
|
amount: *const [u8; 16],
|
||||||
|
out_result: *mut FfiTransferResult,
|
||||||
|
) -> WalletFfiError {
|
||||||
|
let wrapper = match get_wallet(handle) {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => return e,
|
||||||
|
};
|
||||||
|
|
||||||
|
if from.is_null() || to_keys.is_null() || amount.is_null() || out_result.is_null() {
|
||||||
|
print_error("Null pointer argument");
|
||||||
|
return WalletFfiError::NullPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
let wallet = match wrapper.core.lock() {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!("Failed to lock wallet: {}", e));
|
||||||
|
return WalletFfiError::InternalError;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let from_id = AccountId::new(unsafe { (*from).data });
|
||||||
|
let to_npk = (*to_keys).npk();
|
||||||
|
let to_vpk = match (*to_keys).vpk() {
|
||||||
|
Ok(vpk) => vpk,
|
||||||
|
Err(e) => {
|
||||||
|
print_error("Invalid viewing key");
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let amount = u128::from_le_bytes(unsafe { *amount });
|
||||||
|
|
||||||
|
let transfer = NativeTokenTransfer(&wallet);
|
||||||
|
|
||||||
|
match block_on(
|
||||||
|
transfer.send_shielded_transfer_to_outer_account(from_id, to_npk, to_vpk, amount),
|
||||||
|
) {
|
||||||
|
Ok(Ok((response, _shared_key))) => {
|
||||||
|
let tx_hash = CString::new(response.tx_hash)
|
||||||
|
.map(|s| s.into_raw())
|
||||||
|
.unwrap_or(ptr::null_mut());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(*out_result).tx_hash = tx_hash;
|
||||||
|
(*out_result).success = true;
|
||||||
}
|
}
|
||||||
|
WalletFfiError::Success
|
||||||
|
}
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
print_error(format!("Transfer failed: {:?}", e));
|
||||||
|
unsafe {
|
||||||
|
(*out_result).tx_hash = ptr::null_mut();
|
||||||
|
(*out_result).success = false;
|
||||||
|
}
|
||||||
|
map_execution_error(e)
|
||||||
|
}
|
||||||
|
Err(e) => e,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a deshielded token transfer.
|
||||||
|
///
|
||||||
|
/// Transfers tokens from a private account to a public account.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
/// - `handle`: Valid wallet handle
|
||||||
|
/// - `from`: Source account ID (must be owned by this wallet)
|
||||||
|
/// - `to`: Destination account ID
|
||||||
|
/// - `amount`: Amount to transfer as little-endian [u8; 16]
|
||||||
|
/// - `out_result`: Output pointer for transfer result
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// - `Success` if the transfer was submitted successfully
|
||||||
|
/// - `InsufficientFunds` if the source account doesn't have enough balance
|
||||||
|
/// - `KeyNotFound` if the source account's signing key is not in this wallet
|
||||||
|
/// - Error code on other failures
|
||||||
|
///
|
||||||
|
/// # Memory
|
||||||
|
/// The result must be freed with `wallet_ffi_free_transfer_result()`.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||||
|
/// - `from` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
/// - `to` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
/// - `amount` must be a valid pointer to a `[u8; 16]` array
|
||||||
|
/// - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wallet_ffi_transfer_deshielded(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
from: *const FfiBytes32,
|
||||||
|
to: *const FfiBytes32,
|
||||||
|
amount: *const [u8; 16],
|
||||||
|
out_result: *mut FfiTransferResult,
|
||||||
|
) -> WalletFfiError {
|
||||||
|
let wrapper = match get_wallet(handle) {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => return e,
|
||||||
|
};
|
||||||
|
|
||||||
|
if from.is_null() || to.is_null() || amount.is_null() || out_result.is_null() {
|
||||||
|
print_error("Null pointer argument");
|
||||||
|
return WalletFfiError::NullPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
let wallet = match wrapper.core.lock() {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!("Failed to lock wallet: {}", e));
|
||||||
|
return WalletFfiError::InternalError;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let from_id = AccountId::new(unsafe { (*from).data });
|
||||||
|
let to_id = AccountId::new(unsafe { (*to).data });
|
||||||
|
let amount = u128::from_le_bytes(unsafe { *amount });
|
||||||
|
|
||||||
|
let transfer = NativeTokenTransfer(&wallet);
|
||||||
|
|
||||||
|
match block_on(transfer.send_deshielded_transfer(from_id, to_id, amount)) {
|
||||||
|
Ok(Ok((response, _shared_key))) => {
|
||||||
|
let tx_hash = CString::new(response.tx_hash)
|
||||||
|
.map(|s| s.into_raw())
|
||||||
|
.unwrap_or(ptr::null_mut());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(*out_result).tx_hash = tx_hash;
|
||||||
|
(*out_result).success = true;
|
||||||
|
}
|
||||||
|
WalletFfiError::Success
|
||||||
|
}
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
print_error(format!("Transfer failed: {:?}", e));
|
||||||
|
unsafe {
|
||||||
|
(*out_result).tx_hash = ptr::null_mut();
|
||||||
|
(*out_result).success = false;
|
||||||
|
}
|
||||||
|
map_execution_error(e)
|
||||||
|
}
|
||||||
|
Err(e) => e,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a private token transfer.
|
||||||
|
///
|
||||||
|
/// Transfers tokens from a private account to another private account.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
/// - `handle`: Valid wallet handle
|
||||||
|
/// - `from`: Source account ID (must be owned by this wallet)
|
||||||
|
/// - `to_keys`: Destination account keys
|
||||||
|
/// - `amount`: Amount to transfer as little-endian [u8; 16]
|
||||||
|
/// - `out_result`: Output pointer for transfer result
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// - `Success` if the transfer was submitted successfully
|
||||||
|
/// - `InsufficientFunds` if the source account doesn't have enough balance
|
||||||
|
/// - `KeyNotFound` if the source account's signing key is not in this wallet
|
||||||
|
/// - Error code on other failures
|
||||||
|
///
|
||||||
|
/// # Memory
|
||||||
|
/// The result must be freed with `wallet_ffi_free_transfer_result()`.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||||
|
/// - `from` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
/// - `to_keys` must be a valid pointer to a `FfiPrivateAccountKeys` struct
|
||||||
|
/// - `amount` must be a valid pointer to a `[u8; 16]` array
|
||||||
|
/// - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wallet_ffi_transfer_private(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
from: *const FfiBytes32,
|
||||||
|
to_keys: *const FfiPrivateAccountKeys,
|
||||||
|
amount: *const [u8; 16],
|
||||||
|
out_result: *mut FfiTransferResult,
|
||||||
|
) -> WalletFfiError {
|
||||||
|
let wrapper = match get_wallet(handle) {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => return e,
|
||||||
|
};
|
||||||
|
|
||||||
|
if from.is_null() || to_keys.is_null() || amount.is_null() || out_result.is_null() {
|
||||||
|
print_error("Null pointer argument");
|
||||||
|
return WalletFfiError::NullPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
let wallet = match wrapper.core.lock() {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!("Failed to lock wallet: {}", e));
|
||||||
|
return WalletFfiError::InternalError;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let from_id = AccountId::new(unsafe { (*from).data });
|
||||||
|
let to_npk = (*to_keys).npk();
|
||||||
|
let to_vpk = match (*to_keys).vpk() {
|
||||||
|
Ok(vpk) => vpk,
|
||||||
|
Err(e) => {
|
||||||
|
print_error("Invalid viewing key");
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let amount = u128::from_le_bytes(unsafe { *amount });
|
||||||
|
|
||||||
|
let transfer = NativeTokenTransfer(&wallet);
|
||||||
|
|
||||||
|
match block_on(transfer.send_private_transfer_to_outer_account(from_id, to_npk, to_vpk, amount))
|
||||||
|
{
|
||||||
|
Ok(Ok((response, _shared_key))) => {
|
||||||
|
let tx_hash = CString::new(response.tx_hash)
|
||||||
|
.map(|s| s.into_raw())
|
||||||
|
.unwrap_or(ptr::null_mut());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(*out_result).tx_hash = tx_hash;
|
||||||
|
(*out_result).success = true;
|
||||||
|
}
|
||||||
|
WalletFfiError::Success
|
||||||
|
}
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
print_error(format!("Transfer failed: {:?}", e));
|
||||||
|
unsafe {
|
||||||
|
(*out_result).tx_hash = ptr::null_mut();
|
||||||
|
(*out_result).success = false;
|
||||||
|
}
|
||||||
|
map_execution_error(e)
|
||||||
}
|
}
|
||||||
Err(e) => e,
|
Err(e) => e,
|
||||||
}
|
}
|
||||||
@ -168,12 +426,80 @@ pub unsafe extern "C" fn wallet_ffi_register_public_account(
|
|||||||
(*out_result).tx_hash = ptr::null_mut();
|
(*out_result).tx_hash = ptr::null_mut();
|
||||||
(*out_result).success = false;
|
(*out_result).success = false;
|
||||||
}
|
}
|
||||||
match e {
|
map_execution_error(e)
|
||||||
ExecutionFailureKind::KeyNotFoundError => WalletFfiError::KeyNotFound,
|
}
|
||||||
ExecutionFailureKind::SequencerError => WalletFfiError::NetworkError,
|
Err(e) => e,
|
||||||
ExecutionFailureKind::SequencerClientError(_) => WalletFfiError::NetworkError,
|
}
|
||||||
_ => WalletFfiError::InternalError,
|
}
|
||||||
|
|
||||||
|
/// Register a private account on the network.
|
||||||
|
///
|
||||||
|
/// This initializes a private account. The account must be
|
||||||
|
/// owned by this wallet.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
/// - `handle`: Valid wallet handle
|
||||||
|
/// - `account_id`: Account ID to register
|
||||||
|
/// - `out_result`: Output pointer for registration result
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// - `Success` if the registration was submitted successfully
|
||||||
|
/// - Error code on failure
|
||||||
|
///
|
||||||
|
/// # Memory
|
||||||
|
/// The result must be freed with `wallet_ffi_free_transfer_result()`.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||||
|
/// - `account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
/// - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wallet_ffi_register_private_account(
|
||||||
|
handle: *mut WalletHandle,
|
||||||
|
account_id: *const FfiBytes32,
|
||||||
|
out_result: *mut FfiTransferResult,
|
||||||
|
) -> WalletFfiError {
|
||||||
|
let wrapper = match get_wallet(handle) {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => return e,
|
||||||
|
};
|
||||||
|
|
||||||
|
if account_id.is_null() || out_result.is_null() {
|
||||||
|
print_error("Null pointer argument");
|
||||||
|
return WalletFfiError::NullPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
let wallet = match wrapper.core.lock() {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!("Failed to lock wallet: {}", e));
|
||||||
|
return WalletFfiError::InternalError;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let account_id = AccountId::new(unsafe { (*account_id).data });
|
||||||
|
|
||||||
|
let transfer = NativeTokenTransfer(&wallet);
|
||||||
|
|
||||||
|
match block_on(transfer.register_account_private(account_id)) {
|
||||||
|
Ok(Ok((res, _secret))) => {
|
||||||
|
let tx_hash = CString::new(res.tx_hash)
|
||||||
|
.map(|s| s.into_raw())
|
||||||
|
.unwrap_or(ptr::null_mut());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(*out_result).tx_hash = tx_hash;
|
||||||
|
(*out_result).success = true;
|
||||||
}
|
}
|
||||||
|
WalletFfiError::Success
|
||||||
|
}
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
print_error(format!("Registration failed: {:?}", e));
|
||||||
|
unsafe {
|
||||||
|
(*out_result).tx_hash = ptr::null_mut();
|
||||||
|
(*out_result).success = false;
|
||||||
|
}
|
||||||
|
map_execution_error(e)
|
||||||
}
|
}
|
||||||
Err(e) => e,
|
Err(e) => e,
|
||||||
}
|
}
|
||||||
@ -197,3 +523,13 @@ pub unsafe extern "C" fn wallet_ffi_free_transfer_result(result: *mut FfiTransfe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn map_execution_error(e: ExecutionFailureKind) -> WalletFfiError {
|
||||||
|
match e {
|
||||||
|
ExecutionFailureKind::InsufficientFundsError => WalletFfiError::InsufficientFunds,
|
||||||
|
ExecutionFailureKind::KeyNotFoundError => WalletFfiError::KeyNotFound,
|
||||||
|
ExecutionFailureKind::SequencerError => WalletFfiError::NetworkError,
|
||||||
|
ExecutionFailureKind::SequencerClientError(_) => WalletFfiError::NetworkError,
|
||||||
|
_ => WalletFfiError::InternalError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -72,18 +72,18 @@ impl Default for FfiAccount {
|
|||||||
pub struct FfiPrivateAccountKeys {
|
pub struct FfiPrivateAccountKeys {
|
||||||
/// Nullifier public key (32 bytes)
|
/// Nullifier public key (32 bytes)
|
||||||
pub nullifier_public_key: FfiBytes32,
|
pub nullifier_public_key: FfiBytes32,
|
||||||
/// Incoming viewing public key (compressed secp256k1 point)
|
/// viewing public key (compressed secp256k1 point)
|
||||||
pub incoming_viewing_public_key: *const u8,
|
pub viewing_public_key: *const u8,
|
||||||
/// Length of incoming viewing public key (typically 33 bytes)
|
/// Length of viewing public key (typically 33 bytes)
|
||||||
pub incoming_viewing_public_key_len: usize,
|
pub viewing_public_key_len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FfiPrivateAccountKeys {
|
impl Default for FfiPrivateAccountKeys {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
nullifier_public_key: FfiBytes32::default(),
|
nullifier_public_key: FfiBytes32::default(),
|
||||||
incoming_viewing_public_key: std::ptr::null(),
|
viewing_public_key: std::ptr::null(),
|
||||||
incoming_viewing_public_key_len: 0,
|
viewing_public_key_len: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,13 +157,10 @@ impl FfiPrivateAccountKeys {
|
|||||||
nssa_core::NullifierPublicKey(self.nullifier_public_key.data)
|
nssa_core::NullifierPublicKey(self.nullifier_public_key.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ivk(&self) -> Result<nssa_core::encryption::IncomingViewingPublicKey, WalletFfiError> {
|
pub fn vpk(&self) -> Result<nssa_core::encryption::ViewingPublicKey, WalletFfiError> {
|
||||||
if self.incoming_viewing_public_key_len == 33 {
|
if self.viewing_public_key_len == 33 {
|
||||||
let slice = unsafe {
|
let slice = unsafe {
|
||||||
slice::from_raw_parts(
|
slice::from_raw_parts(self.viewing_public_key, self.viewing_public_key_len)
|
||||||
self.incoming_viewing_public_key,
|
|
||||||
self.incoming_viewing_public_key_len,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
Ok(Secp256k1Point(slice.to_vec()))
|
Ok(Secp256k1Point(slice.to_vec()))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -198,13 +198,13 @@ typedef struct FfiPrivateAccountKeys {
|
|||||||
*/
|
*/
|
||||||
struct FfiBytes32 nullifier_public_key;
|
struct FfiBytes32 nullifier_public_key;
|
||||||
/**
|
/**
|
||||||
* Incoming viewing public key (compressed secp256k1 point)
|
* viewing public key (compressed secp256k1 point)
|
||||||
*/
|
*/
|
||||||
const uint8_t *incoming_viewing_public_key;
|
const uint8_t *viewing_public_key;
|
||||||
/**
|
/**
|
||||||
* Length of incoming viewing public key (typically 33 bytes)
|
* Length of viewing public key (typically 33 bytes)
|
||||||
*/
|
*/
|
||||||
uintptr_t incoming_viewing_public_key_len;
|
uintptr_t viewing_public_key_len;
|
||||||
} FfiPrivateAccountKeys;
|
} FfiPrivateAccountKeys;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -344,6 +344,30 @@ enum WalletFfiError wallet_ffi_get_account_public(struct WalletHandle *handle,
|
|||||||
const struct FfiBytes32 *account_id,
|
const struct FfiBytes32 *account_id,
|
||||||
struct FfiAccount *out_account);
|
struct FfiAccount *out_account);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get full private account data from the local storage.
|
||||||
|
*
|
||||||
|
* # Parameters
|
||||||
|
* - `handle`: Valid wallet handle
|
||||||
|
* - `account_id`: The account ID (32 bytes)
|
||||||
|
* - `out_account`: Output pointer for account data
|
||||||
|
*
|
||||||
|
* # Returns
|
||||||
|
* - `Success` on successful query
|
||||||
|
* - Error code on failure
|
||||||
|
*
|
||||||
|
* # Memory
|
||||||
|
* The account data must be freed with `wallet_ffi_free_account_data()`.
|
||||||
|
*
|
||||||
|
* # Safety
|
||||||
|
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||||
|
* - `account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
* - `out_account` must be a valid pointer to a `FfiAccount` struct
|
||||||
|
*/
|
||||||
|
enum WalletFfiError wallet_ffi_get_account_private(struct WalletHandle *handle,
|
||||||
|
const struct FfiBytes32 *account_id,
|
||||||
|
struct FfiAccount *out_account);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free account data returned by `wallet_ffi_get_account_public`.
|
* Free account data returned by `wallet_ffi_get_account_public`.
|
||||||
*
|
*
|
||||||
@ -380,7 +404,7 @@ enum WalletFfiError wallet_ffi_get_public_account_key(struct WalletHandle *handl
|
|||||||
/**
|
/**
|
||||||
* Get keys for a private account.
|
* Get keys for a private account.
|
||||||
*
|
*
|
||||||
* Returns the nullifier public key (NPK) and incoming viewing public key (IPK)
|
* Returns the nullifier public key (NPK) and viewing public key (VPK)
|
||||||
* for the specified private account. These keys are safe to share publicly.
|
* for the specified private account. These keys are safe to share publicly.
|
||||||
*
|
*
|
||||||
* # Parameters
|
* # Parameters
|
||||||
@ -546,6 +570,108 @@ enum WalletFfiError wallet_ffi_transfer_public(struct WalletHandle *handle,
|
|||||||
const uint8_t (*amount)[16],
|
const uint8_t (*amount)[16],
|
||||||
struct FfiTransferResult *out_result);
|
struct FfiTransferResult *out_result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a shielded token transfer.
|
||||||
|
*
|
||||||
|
* Transfers tokens from a public account to a private account.
|
||||||
|
*
|
||||||
|
* # Parameters
|
||||||
|
* - `handle`: Valid wallet handle
|
||||||
|
* - `from`: Source account ID (must be owned by this wallet)
|
||||||
|
* - `to_keys`: Destination account keys
|
||||||
|
* - `amount`: Amount to transfer as little-endian [u8; 16]
|
||||||
|
* - `out_result`: Output pointer for transfer result
|
||||||
|
*
|
||||||
|
* # Returns
|
||||||
|
* - `Success` if the transfer was submitted successfully
|
||||||
|
* - `InsufficientFunds` if the source account doesn't have enough balance
|
||||||
|
* - `KeyNotFound` if the source account's signing key is not in this wallet
|
||||||
|
* - Error code on other failures
|
||||||
|
*
|
||||||
|
* # Memory
|
||||||
|
* The result must be freed with `wallet_ffi_free_transfer_result()`.
|
||||||
|
*
|
||||||
|
* # Safety
|
||||||
|
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||||
|
* - `from` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
* - `to_keys` must be a valid pointer to a `FfiPrivateAccountKeys` struct
|
||||||
|
* - `amount` must be a valid pointer to a `[u8; 16]` array
|
||||||
|
* - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
||||||
|
*/
|
||||||
|
enum WalletFfiError wallet_ffi_transfer_shielded(struct WalletHandle *handle,
|
||||||
|
const struct FfiBytes32 *from,
|
||||||
|
const struct FfiPrivateAccountKeys *to_keys,
|
||||||
|
const uint8_t (*amount)[16],
|
||||||
|
struct FfiTransferResult *out_result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a deshielded token transfer.
|
||||||
|
*
|
||||||
|
* Transfers tokens from a private account to a public account.
|
||||||
|
*
|
||||||
|
* # Parameters
|
||||||
|
* - `handle`: Valid wallet handle
|
||||||
|
* - `from`: Source account ID (must be owned by this wallet)
|
||||||
|
* - `to`: Destination account ID
|
||||||
|
* - `amount`: Amount to transfer as little-endian [u8; 16]
|
||||||
|
* - `out_result`: Output pointer for transfer result
|
||||||
|
*
|
||||||
|
* # Returns
|
||||||
|
* - `Success` if the transfer was submitted successfully
|
||||||
|
* - `InsufficientFunds` if the source account doesn't have enough balance
|
||||||
|
* - `KeyNotFound` if the source account's signing key is not in this wallet
|
||||||
|
* - Error code on other failures
|
||||||
|
*
|
||||||
|
* # Memory
|
||||||
|
* The result must be freed with `wallet_ffi_free_transfer_result()`.
|
||||||
|
*
|
||||||
|
* # Safety
|
||||||
|
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||||
|
* - `from` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
* - `to` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
* - `amount` must be a valid pointer to a `[u8; 16]` array
|
||||||
|
* - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
||||||
|
*/
|
||||||
|
enum WalletFfiError wallet_ffi_transfer_deshielded(struct WalletHandle *handle,
|
||||||
|
const struct FfiBytes32 *from,
|
||||||
|
const struct FfiBytes32 *to,
|
||||||
|
const uint8_t (*amount)[16],
|
||||||
|
struct FfiTransferResult *out_result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a private token transfer.
|
||||||
|
*
|
||||||
|
* Transfers tokens from a private account to another private account.
|
||||||
|
*
|
||||||
|
* # Parameters
|
||||||
|
* - `handle`: Valid wallet handle
|
||||||
|
* - `from`: Source account ID (must be owned by this wallet)
|
||||||
|
* - `to_keys`: Destination account keys
|
||||||
|
* - `amount`: Amount to transfer as little-endian [u8; 16]
|
||||||
|
* - `out_result`: Output pointer for transfer result
|
||||||
|
*
|
||||||
|
* # Returns
|
||||||
|
* - `Success` if the transfer was submitted successfully
|
||||||
|
* - `InsufficientFunds` if the source account doesn't have enough balance
|
||||||
|
* - `KeyNotFound` if the source account's signing key is not in this wallet
|
||||||
|
* - Error code on other failures
|
||||||
|
*
|
||||||
|
* # Memory
|
||||||
|
* The result must be freed with `wallet_ffi_free_transfer_result()`.
|
||||||
|
*
|
||||||
|
* # Safety
|
||||||
|
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||||
|
* - `from` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
* - `to_keys` must be a valid pointer to a `FfiPrivateAccountKeys` struct
|
||||||
|
* - `amount` must be a valid pointer to a `[u8; 16]` array
|
||||||
|
* - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
||||||
|
*/
|
||||||
|
enum WalletFfiError wallet_ffi_transfer_private(struct WalletHandle *handle,
|
||||||
|
const struct FfiBytes32 *from,
|
||||||
|
const struct FfiPrivateAccountKeys *to_keys,
|
||||||
|
const uint8_t (*amount)[16],
|
||||||
|
struct FfiTransferResult *out_result);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a public account on the network.
|
* Register a public account on the network.
|
||||||
*
|
*
|
||||||
@ -573,6 +699,33 @@ enum WalletFfiError wallet_ffi_register_public_account(struct WalletHandle *hand
|
|||||||
const struct FfiBytes32 *account_id,
|
const struct FfiBytes32 *account_id,
|
||||||
struct FfiTransferResult *out_result);
|
struct FfiTransferResult *out_result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a private account on the network.
|
||||||
|
*
|
||||||
|
* This initializes a private account. The account must be
|
||||||
|
* owned by this wallet.
|
||||||
|
*
|
||||||
|
* # Parameters
|
||||||
|
* - `handle`: Valid wallet handle
|
||||||
|
* - `account_id`: Account ID to register
|
||||||
|
* - `out_result`: Output pointer for registration result
|
||||||
|
*
|
||||||
|
* # Returns
|
||||||
|
* - `Success` if the registration was submitted successfully
|
||||||
|
* - Error code on failure
|
||||||
|
*
|
||||||
|
* # Memory
|
||||||
|
* The result must be freed with `wallet_ffi_free_transfer_result()`.
|
||||||
|
*
|
||||||
|
* # Safety
|
||||||
|
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||||
|
* - `account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||||
|
* - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
||||||
|
*/
|
||||||
|
enum WalletFfiError wallet_ffi_register_private_account(struct WalletHandle *handle,
|
||||||
|
const struct FfiBytes32 *account_id,
|
||||||
|
struct FfiTransferResult *out_result);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a transfer result returned by `wallet_ffi_transfer_public` or
|
* Free a transfer result returned by `wallet_ffi_transfer_public` or
|
||||||
* `wallet_ffi_register_public_account`.
|
* `wallet_ffi_register_public_account`.
|
||||||
|
|||||||
@ -84,9 +84,9 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Private": {
|
"Private": {
|
||||||
"account_id": "3oCG8gqdKLMegw4rRfyaMQvuPHpcASt7xwttsmnZLSkw",
|
"account_id": "2ECgkFTaXzwjJBXR7ZKmXYQtpHbvTTHK9Auma4NL9AUo",
|
||||||
"account": {
|
"account": {
|
||||||
"program_owner": [
|
"program_owner": [
|
||||||
0,
|
0,
|
||||||
@ -103,219 +103,19 @@
|
|||||||
"nonce": 0
|
"nonce": 0
|
||||||
},
|
},
|
||||||
"key_chain": {
|
"key_chain": {
|
||||||
"secret_spending_key": [
|
"secret_spending_key": [112, 17, 152, 192, 217, 201, 142, 92, 111, 68, 85, 222, 107, 73, 78, 196, 118, 226, 37, 17, 185, 177, 149, 182, 9, 85, 187, 152, 163, 144, 68, 121],
|
||||||
251,
|
|
||||||
82,
|
|
||||||
235,
|
|
||||||
1,
|
|
||||||
146,
|
|
||||||
96,
|
|
||||||
30,
|
|
||||||
81,
|
|
||||||
162,
|
|
||||||
234,
|
|
||||||
33,
|
|
||||||
15,
|
|
||||||
123,
|
|
||||||
129,
|
|
||||||
116,
|
|
||||||
0,
|
|
||||||
84,
|
|
||||||
136,
|
|
||||||
176,
|
|
||||||
70,
|
|
||||||
190,
|
|
||||||
224,
|
|
||||||
161,
|
|
||||||
54,
|
|
||||||
134,
|
|
||||||
142,
|
|
||||||
154,
|
|
||||||
1,
|
|
||||||
18,
|
|
||||||
251,
|
|
||||||
242,
|
|
||||||
189
|
|
||||||
],
|
|
||||||
"private_key_holder": {
|
"private_key_holder": {
|
||||||
"nullifier_secret_key": [
|
"nullifier_secret_key": [52, 33, 235, 245, 42, 132, 163, 182, 114, 56, 144, 187, 147, 23, 184, 227, 128, 12, 180, 142, 217, 110, 188, 177, 155, 141, 23, 127, 216, 185, 33, 126],
|
||||||
29,
|
"viewing_secret_key": [44, 81, 165, 166, 34, 188, 192, 240, 40, 9, 83, 189, 215, 184, 246, 154, 247, 227, 155, 16, 121, 238, 4, 245, 63, 135, 192, 213, 222, 247, 120, 86]
|
||||||
250,
|
|
||||||
10,
|
|
||||||
187,
|
|
||||||
35,
|
|
||||||
123,
|
|
||||||
180,
|
|
||||||
250,
|
|
||||||
246,
|
|
||||||
97,
|
|
||||||
216,
|
|
||||||
153,
|
|
||||||
44,
|
|
||||||
156,
|
|
||||||
16,
|
|
||||||
93,
|
|
||||||
241,
|
|
||||||
26,
|
|
||||||
174,
|
|
||||||
219,
|
|
||||||
72,
|
|
||||||
84,
|
|
||||||
34,
|
|
||||||
247,
|
|
||||||
112,
|
|
||||||
101,
|
|
||||||
217,
|
|
||||||
243,
|
|
||||||
189,
|
|
||||||
173,
|
|
||||||
75,
|
|
||||||
20
|
|
||||||
],
|
|
||||||
"incoming_viewing_secret_key": [
|
|
||||||
251,
|
|
||||||
201,
|
|
||||||
22,
|
|
||||||
154,
|
|
||||||
100,
|
|
||||||
165,
|
|
||||||
218,
|
|
||||||
108,
|
|
||||||
163,
|
|
||||||
190,
|
|
||||||
135,
|
|
||||||
91,
|
|
||||||
145,
|
|
||||||
84,
|
|
||||||
69,
|
|
||||||
241,
|
|
||||||
46,
|
|
||||||
117,
|
|
||||||
217,
|
|
||||||
110,
|
|
||||||
197,
|
|
||||||
248,
|
|
||||||
91,
|
|
||||||
193,
|
|
||||||
14,
|
|
||||||
104,
|
|
||||||
88,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
153,
|
|
||||||
182,
|
|
||||||
158
|
|
||||||
],
|
|
||||||
"outgoing_viewing_secret_key": [
|
|
||||||
25,
|
|
||||||
67,
|
|
||||||
121,
|
|
||||||
76,
|
|
||||||
175,
|
|
||||||
100,
|
|
||||||
30,
|
|
||||||
198,
|
|
||||||
105,
|
|
||||||
123,
|
|
||||||
49,
|
|
||||||
169,
|
|
||||||
75,
|
|
||||||
178,
|
|
||||||
75,
|
|
||||||
210,
|
|
||||||
100,
|
|
||||||
143,
|
|
||||||
210,
|
|
||||||
243,
|
|
||||||
228,
|
|
||||||
243,
|
|
||||||
21,
|
|
||||||
18,
|
|
||||||
36,
|
|
||||||
84,
|
|
||||||
164,
|
|
||||||
186,
|
|
||||||
139,
|
|
||||||
113,
|
|
||||||
214,
|
|
||||||
12
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"nullifer_public_key": [
|
"nullifer_public_key": [13, 25, 40, 5, 198, 248, 210, 248, 237, 121, 124, 145, 186, 142, 253, 216, 236, 69, 193, 32, 166, 167, 49, 133, 172, 111, 159, 46, 84, 17, 157, 23],
|
||||||
63,
|
"viewing_public_key": [3, 43, 116, 165, 161, 27, 150, 158, 175, 198, 215, 27, 121, 126, 158, 224, 249, 92, 168, 163, 173, 115, 120, 122, 89, 173, 133, 94, 39, 238, 62, 52, 193]
|
||||||
202,
|
|
||||||
178,
|
|
||||||
231,
|
|
||||||
183,
|
|
||||||
82,
|
|
||||||
237,
|
|
||||||
212,
|
|
||||||
216,
|
|
||||||
221,
|
|
||||||
215,
|
|
||||||
255,
|
|
||||||
153,
|
|
||||||
101,
|
|
||||||
177,
|
|
||||||
161,
|
|
||||||
254,
|
|
||||||
210,
|
|
||||||
128,
|
|
||||||
122,
|
|
||||||
54,
|
|
||||||
190,
|
|
||||||
230,
|
|
||||||
151,
|
|
||||||
183,
|
|
||||||
64,
|
|
||||||
225,
|
|
||||||
229,
|
|
||||||
113,
|
|
||||||
1,
|
|
||||||
228,
|
|
||||||
97
|
|
||||||
],
|
|
||||||
"incoming_viewing_public_key": [
|
|
||||||
3,
|
|
||||||
235,
|
|
||||||
139,
|
|
||||||
131,
|
|
||||||
237,
|
|
||||||
177,
|
|
||||||
122,
|
|
||||||
189,
|
|
||||||
6,
|
|
||||||
177,
|
|
||||||
167,
|
|
||||||
178,
|
|
||||||
202,
|
|
||||||
117,
|
|
||||||
246,
|
|
||||||
58,
|
|
||||||
28,
|
|
||||||
65,
|
|
||||||
132,
|
|
||||||
79,
|
|
||||||
220,
|
|
||||||
139,
|
|
||||||
119,
|
|
||||||
243,
|
|
||||||
187,
|
|
||||||
160,
|
|
||||||
212,
|
|
||||||
121,
|
|
||||||
61,
|
|
||||||
247,
|
|
||||||
116,
|
|
||||||
72,
|
|
||||||
205
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Private": {
|
"Private": {
|
||||||
"account_id": "AKTcXgJ1xoynta1Ec7y6Jso1z1JQtHqd7aPQ1h9er6xX",
|
"account_id": "E8HwiTyQe4H9HK7icTvn95HQMnzx49mP9A2ddtMLpNaN",
|
||||||
"account": {
|
"account": {
|
||||||
"program_owner": [
|
"program_owner": [
|
||||||
0,
|
0,
|
||||||
@ -332,213 +132,13 @@
|
|||||||
"nonce": 0
|
"nonce": 0
|
||||||
},
|
},
|
||||||
"key_chain": {
|
"key_chain": {
|
||||||
"secret_spending_key": [
|
"secret_spending_key": [48, 175, 124, 10, 230, 240, 166, 14, 249, 254, 157, 226, 208, 124, 122, 177, 203, 139, 192, 180, 43, 120, 55, 151, 50, 21, 113, 22, 254, 83, 148, 56],
|
||||||
238,
|
|
||||||
171,
|
|
||||||
241,
|
|
||||||
69,
|
|
||||||
111,
|
|
||||||
217,
|
|
||||||
85,
|
|
||||||
64,
|
|
||||||
19,
|
|
||||||
82,
|
|
||||||
18,
|
|
||||||
189,
|
|
||||||
32,
|
|
||||||
91,
|
|
||||||
78,
|
|
||||||
175,
|
|
||||||
107,
|
|
||||||
7,
|
|
||||||
109,
|
|
||||||
60,
|
|
||||||
52,
|
|
||||||
44,
|
|
||||||
243,
|
|
||||||
230,
|
|
||||||
72,
|
|
||||||
244,
|
|
||||||
192,
|
|
||||||
92,
|
|
||||||
137,
|
|
||||||
33,
|
|
||||||
118,
|
|
||||||
254
|
|
||||||
],
|
|
||||||
"private_key_holder": {
|
"private_key_holder": {
|
||||||
"nullifier_secret_key": [
|
"nullifier_secret_key": [99, 82, 190, 140, 234, 10, 61, 163, 15, 211, 179, 54, 70, 166, 87, 5, 182, 68, 117, 244, 217, 23, 99, 9, 4, 177, 230, 125, 109, 91, 160, 30],
|
||||||
25,
|
"viewing_secret_key": [205, 32, 76, 251, 255, 236, 96, 119, 61, 111, 65, 100, 75, 218, 12, 22, 17, 170, 55, 226, 21, 154, 161, 34, 208, 74, 27, 1, 119, 13, 88, 128]
|
||||||
211,
|
|
||||||
215,
|
|
||||||
119,
|
|
||||||
57,
|
|
||||||
223,
|
|
||||||
247,
|
|
||||||
37,
|
|
||||||
245,
|
|
||||||
144,
|
|
||||||
122,
|
|
||||||
29,
|
|
||||||
118,
|
|
||||||
245,
|
|
||||||
83,
|
|
||||||
228,
|
|
||||||
23,
|
|
||||||
9,
|
|
||||||
101,
|
|
||||||
120,
|
|
||||||
88,
|
|
||||||
33,
|
|
||||||
238,
|
|
||||||
207,
|
|
||||||
128,
|
|
||||||
61,
|
|
||||||
110,
|
|
||||||
2,
|
|
||||||
89,
|
|
||||||
62,
|
|
||||||
164,
|
|
||||||
13
|
|
||||||
],
|
|
||||||
"incoming_viewing_secret_key": [
|
|
||||||
193,
|
|
||||||
181,
|
|
||||||
14,
|
|
||||||
196,
|
|
||||||
142,
|
|
||||||
84,
|
|
||||||
15,
|
|
||||||
65,
|
|
||||||
128,
|
|
||||||
101,
|
|
||||||
70,
|
|
||||||
196,
|
|
||||||
241,
|
|
||||||
47,
|
|
||||||
130,
|
|
||||||
221,
|
|
||||||
23,
|
|
||||||
146,
|
|
||||||
161,
|
|
||||||
237,
|
|
||||||
221,
|
|
||||||
40,
|
|
||||||
19,
|
|
||||||
126,
|
|
||||||
59,
|
|
||||||
15,
|
|
||||||
169,
|
|
||||||
236,
|
|
||||||
25,
|
|
||||||
105,
|
|
||||||
104,
|
|
||||||
231
|
|
||||||
],
|
|
||||||
"outgoing_viewing_secret_key": [
|
|
||||||
20,
|
|
||||||
170,
|
|
||||||
220,
|
|
||||||
108,
|
|
||||||
41,
|
|
||||||
23,
|
|
||||||
155,
|
|
||||||
217,
|
|
||||||
247,
|
|
||||||
190,
|
|
||||||
175,
|
|
||||||
168,
|
|
||||||
247,
|
|
||||||
34,
|
|
||||||
105,
|
|
||||||
134,
|
|
||||||
114,
|
|
||||||
74,
|
|
||||||
104,
|
|
||||||
91,
|
|
||||||
211,
|
|
||||||
62,
|
|
||||||
126,
|
|
||||||
13,
|
|
||||||
130,
|
|
||||||
100,
|
|
||||||
241,
|
|
||||||
214,
|
|
||||||
250,
|
|
||||||
236,
|
|
||||||
38,
|
|
||||||
150
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"nullifer_public_key": [
|
"nullifer_public_key": [32, 67, 72, 164, 106, 53, 66, 239, 141, 15, 52, 230, 136, 177, 2, 236, 207, 243, 134, 135, 210, 143, 87, 232, 215, 128, 194, 120, 113, 224, 4, 165],
|
||||||
192,
|
"viewing_public_key": [2, 79, 110, 46, 203, 29, 206, 205, 18, 86, 27, 189, 104, 103, 113, 181, 110, 53, 78, 172, 11, 171, 190, 18, 126, 214, 81, 77, 192, 154, 58, 195, 238]
|
||||||
251,
|
|
||||||
166,
|
|
||||||
243,
|
|
||||||
167,
|
|
||||||
236,
|
|
||||||
84,
|
|
||||||
249,
|
|
||||||
35,
|
|
||||||
136,
|
|
||||||
130,
|
|
||||||
172,
|
|
||||||
219,
|
|
||||||
225,
|
|
||||||
161,
|
|
||||||
139,
|
|
||||||
229,
|
|
||||||
89,
|
|
||||||
243,
|
|
||||||
125,
|
|
||||||
194,
|
|
||||||
213,
|
|
||||||
209,
|
|
||||||
30,
|
|
||||||
23,
|
|
||||||
174,
|
|
||||||
100,
|
|
||||||
244,
|
|
||||||
124,
|
|
||||||
74,
|
|
||||||
140,
|
|
||||||
47
|
|
||||||
],
|
|
||||||
"incoming_viewing_public_key": [
|
|
||||||
2,
|
|
||||||
181,
|
|
||||||
98,
|
|
||||||
93,
|
|
||||||
216,
|
|
||||||
241,
|
|
||||||
241,
|
|
||||||
110,
|
|
||||||
58,
|
|
||||||
198,
|
|
||||||
119,
|
|
||||||
174,
|
|
||||||
250,
|
|
||||||
184,
|
|
||||||
1,
|
|
||||||
204,
|
|
||||||
200,
|
|
||||||
173,
|
|
||||||
44,
|
|
||||||
238,
|
|
||||||
37,
|
|
||||||
247,
|
|
||||||
170,
|
|
||||||
156,
|
|
||||||
100,
|
|
||||||
254,
|
|
||||||
116,
|
|
||||||
242,
|
|
||||||
28,
|
|
||||||
183,
|
|
||||||
187,
|
|
||||||
77,
|
|
||||||
255
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ pub enum AccountSubcommand {
|
|||||||
/// Flag to get raw account data
|
/// Flag to get raw account data
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
raw: bool,
|
raw: bool,
|
||||||
/// Display keys (pk for public accounts, npk/ipk for private accounts)
|
/// Display keys (pk for public accounts, npk/vpk for private accounts)
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
keys: bool,
|
keys: bool,
|
||||||
/// Valid 32 byte base58 string with privacy prefix
|
/// Valid 32 byte base58 string with privacy prefix
|
||||||
@ -107,8 +107,8 @@ impl WalletSubcommand for NewSubcommand {
|
|||||||
);
|
);
|
||||||
println!("With npk {}", hex::encode(key.nullifer_public_key.0));
|
println!("With npk {}", hex::encode(key.nullifer_public_key.0));
|
||||||
println!(
|
println!(
|
||||||
"With ipk {}",
|
"With vpk {}",
|
||||||
hex::encode(key.incoming_viewing_public_key.to_bytes())
|
hex::encode(key.viewing_public_key.to_bytes())
|
||||||
);
|
);
|
||||||
|
|
||||||
wallet_core.store_persistent_data().await?;
|
wallet_core.store_persistent_data().await?;
|
||||||
@ -207,10 +207,7 @@ impl WalletSubcommand for AccountSubcommand {
|
|||||||
.ok_or(anyhow::anyhow!("Private account not found in storage"))?;
|
.ok_or(anyhow::anyhow!("Private account not found in storage"))?;
|
||||||
|
|
||||||
println!("npk {}", hex::encode(key.nullifer_public_key.0));
|
println!("npk {}", hex::encode(key.nullifer_public_key.0));
|
||||||
println!(
|
println!("vpk {}", hex::encode(key.viewing_public_key.to_bytes()));
|
||||||
"ipk {}",
|
|
||||||
hex::encode(key.incoming_viewing_public_key.to_bytes())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -22,7 +22,7 @@ pub enum AuthTransferSubcommand {
|
|||||||
},
|
},
|
||||||
/// Send native tokens from one account to another with variable privacy
|
/// Send native tokens from one account to another with variable privacy
|
||||||
///
|
///
|
||||||
/// If receiver is private, then `to` and (`to_npk` , `to_ipk`) is a mutually exclusive
|
/// If receiver is private, then `to` and (`to_npk` , `to_vpk`) is a mutually exclusive
|
||||||
/// patterns.
|
/// patterns.
|
||||||
///
|
///
|
||||||
/// First is used for owned accounts, second otherwise.
|
/// First is used for owned accounts, second otherwise.
|
||||||
@ -36,9 +36,9 @@ pub enum AuthTransferSubcommand {
|
|||||||
/// to_npk - valid 32 byte hex string
|
/// to_npk - valid 32 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
to_npk: Option<String>,
|
to_npk: Option<String>,
|
||||||
/// to_ipk - valid 33 byte hex string
|
/// to_vpk - valid 33 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
to_ipk: Option<String>,
|
to_vpk: Option<String>,
|
||||||
/// amount - amount of balance to move
|
/// amount - amount of balance to move
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
amount: u128,
|
amount: u128,
|
||||||
@ -102,10 +102,10 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
|||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
to_npk,
|
to_npk,
|
||||||
to_ipk,
|
to_vpk,
|
||||||
amount,
|
amount,
|
||||||
} => {
|
} => {
|
||||||
let underlying_subcommand = match (to, to_npk, to_ipk) {
|
let underlying_subcommand = match (to, to_npk, to_vpk) {
|
||||||
(None, None, None) => {
|
(None, None, None) => {
|
||||||
anyhow::bail!(
|
anyhow::bail!(
|
||||||
"Provide either account account_id of receiver or their public keys"
|
"Provide either account account_id of receiver or their public keys"
|
||||||
@ -154,7 +154,7 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(None, Some(to_npk), Some(to_ipk)) => {
|
(None, Some(to_npk), Some(to_vpk)) => {
|
||||||
let (from, from_privacy) = parse_addr_with_privacy_prefix(&from)?;
|
let (from, from_privacy) = parse_addr_with_privacy_prefix(&from)?;
|
||||||
|
|
||||||
match from_privacy {
|
match from_privacy {
|
||||||
@ -163,7 +163,7 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
|||||||
NativeTokenTransferProgramSubcommandPrivate::PrivateForeign {
|
NativeTokenTransferProgramSubcommandPrivate::PrivateForeign {
|
||||||
from,
|
from,
|
||||||
to_npk,
|
to_npk,
|
||||||
to_ipk,
|
to_vpk,
|
||||||
amount,
|
amount,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -173,7 +173,7 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
|||||||
NativeTokenTransferProgramSubcommandShielded::ShieldedForeign {
|
NativeTokenTransferProgramSubcommandShielded::ShieldedForeign {
|
||||||
from,
|
from,
|
||||||
to_npk,
|
to_npk,
|
||||||
to_ipk,
|
to_vpk,
|
||||||
amount,
|
amount,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -255,9 +255,9 @@ pub enum NativeTokenTransferProgramSubcommandShielded {
|
|||||||
/// to_npk - valid 32 byte hex string
|
/// to_npk - valid 32 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
to_npk: String,
|
to_npk: String,
|
||||||
/// to_ipk - valid 33 byte hex string
|
/// to_vpk - valid 33 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
to_ipk: String,
|
to_vpk: String,
|
||||||
/// amount - amount of balance to move
|
/// amount - amount of balance to move
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
amount: u128,
|
amount: u128,
|
||||||
@ -292,9 +292,9 @@ pub enum NativeTokenTransferProgramSubcommandPrivate {
|
|||||||
/// to_npk - valid 32 byte hex string
|
/// to_npk - valid 32 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
to_npk: String,
|
to_npk: String,
|
||||||
/// to_ipk - valid 33 byte hex string
|
/// to_vpk - valid 33 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
to_ipk: String,
|
to_vpk: String,
|
||||||
/// amount - amount of balance to move
|
/// amount - amount of balance to move
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
amount: u128,
|
amount: u128,
|
||||||
@ -336,7 +336,7 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandPrivate {
|
|||||||
NativeTokenTransferProgramSubcommandPrivate::PrivateForeign {
|
NativeTokenTransferProgramSubcommandPrivate::PrivateForeign {
|
||||||
from,
|
from,
|
||||||
to_npk,
|
to_npk,
|
||||||
to_ipk,
|
to_vpk,
|
||||||
amount,
|
amount,
|
||||||
} => {
|
} => {
|
||||||
let from: AccountId = from.parse().unwrap();
|
let from: AccountId = from.parse().unwrap();
|
||||||
@ -345,14 +345,14 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandPrivate {
|
|||||||
to_npk.copy_from_slice(&to_npk_res);
|
to_npk.copy_from_slice(&to_npk_res);
|
||||||
let to_npk = nssa_core::NullifierPublicKey(to_npk);
|
let to_npk = nssa_core::NullifierPublicKey(to_npk);
|
||||||
|
|
||||||
let to_ipk_res = hex::decode(to_ipk)?;
|
let to_vpk_res = hex::decode(to_vpk)?;
|
||||||
let mut to_ipk = [0u8; 33];
|
let mut to_vpk = [0u8; 33];
|
||||||
to_ipk.copy_from_slice(&to_ipk_res);
|
to_vpk.copy_from_slice(&to_vpk_res);
|
||||||
let to_ipk =
|
let to_vpk =
|
||||||
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
|
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_vpk.to_vec());
|
||||||
|
|
||||||
let (res, [secret_from, _]) = NativeTokenTransfer(wallet_core)
|
let (res, [secret_from, _]) = NativeTokenTransfer(wallet_core)
|
||||||
.send_private_transfer_to_outer_account(from, to_npk, to_ipk, amount)
|
.send_private_transfer_to_outer_account(from, to_npk, to_vpk, amount)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("Results of tx send are {res:#?}");
|
println!("Results of tx send are {res:#?}");
|
||||||
@ -412,7 +412,7 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandShielded {
|
|||||||
NativeTokenTransferProgramSubcommandShielded::ShieldedForeign {
|
NativeTokenTransferProgramSubcommandShielded::ShieldedForeign {
|
||||||
from,
|
from,
|
||||||
to_npk,
|
to_npk,
|
||||||
to_ipk,
|
to_vpk,
|
||||||
amount,
|
amount,
|
||||||
} => {
|
} => {
|
||||||
let from: AccountId = from.parse().unwrap();
|
let from: AccountId = from.parse().unwrap();
|
||||||
@ -422,14 +422,14 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandShielded {
|
|||||||
to_npk.copy_from_slice(&to_npk_res);
|
to_npk.copy_from_slice(&to_npk_res);
|
||||||
let to_npk = nssa_core::NullifierPublicKey(to_npk);
|
let to_npk = nssa_core::NullifierPublicKey(to_npk);
|
||||||
|
|
||||||
let to_ipk_res = hex::decode(to_ipk)?;
|
let to_vpk_res = hex::decode(to_vpk)?;
|
||||||
let mut to_ipk = [0u8; 33];
|
let mut to_vpk = [0u8; 33];
|
||||||
to_ipk.copy_from_slice(&to_ipk_res);
|
to_vpk.copy_from_slice(&to_vpk_res);
|
||||||
let to_ipk =
|
let to_vpk =
|
||||||
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
|
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_vpk.to_vec());
|
||||||
|
|
||||||
let (res, _) = NativeTokenTransfer(wallet_core)
|
let (res, _) = NativeTokenTransfer(wallet_core)
|
||||||
.send_shielded_transfer_to_outer_account(from, to_npk, to_ipk, amount)
|
.send_shielded_transfer_to_outer_account(from, to_npk, to_vpk, amount)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("Results of tx send are {res:#?}");
|
println!("Results of tx send are {res:#?}");
|
||||||
|
|||||||
@ -29,7 +29,7 @@ pub enum TokenProgramAgnosticSubcommand {
|
|||||||
},
|
},
|
||||||
/// Send tokens from one account to another with variable privacy
|
/// Send tokens from one account to another with variable privacy
|
||||||
///
|
///
|
||||||
/// If receiver is private, then `to` and (`to_npk` , `to_ipk`) is a mutually exclusive
|
/// If receiver is private, then `to` and (`to_npk` , `to_vpk`) is a mutually exclusive
|
||||||
/// patterns.
|
/// patterns.
|
||||||
///
|
///
|
||||||
/// First is used for owned accounts, second otherwise.
|
/// First is used for owned accounts, second otherwise.
|
||||||
@ -43,9 +43,9 @@ pub enum TokenProgramAgnosticSubcommand {
|
|||||||
/// to_npk - valid 32 byte hex string
|
/// to_npk - valid 32 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
to_npk: Option<String>,
|
to_npk: Option<String>,
|
||||||
/// to_ipk - valid 33 byte hex string
|
/// to_vpk - valid 33 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
to_ipk: Option<String>,
|
to_vpk: Option<String>,
|
||||||
/// amount - amount of balance to move
|
/// amount - amount of balance to move
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
amount: u128,
|
amount: u128,
|
||||||
@ -71,7 +71,7 @@ pub enum TokenProgramAgnosticSubcommand {
|
|||||||
///
|
///
|
||||||
/// `definition` is owned
|
/// `definition` is owned
|
||||||
///
|
///
|
||||||
/// If `holder` is private, then `holder` and (`holder_npk` , `holder_ipk`) is a mutually
|
/// If `holder` is private, then `holder` and (`holder_npk` , `holder_vpk`) is a mutually
|
||||||
/// exclusive patterns.
|
/// exclusive patterns.
|
||||||
///
|
///
|
||||||
/// First is used for owned accounts, second otherwise.
|
/// First is used for owned accounts, second otherwise.
|
||||||
@ -85,9 +85,9 @@ pub enum TokenProgramAgnosticSubcommand {
|
|||||||
/// holder_npk - valid 32 byte hex string
|
/// holder_npk - valid 32 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
holder_npk: Option<String>,
|
holder_npk: Option<String>,
|
||||||
/// to_ipk - valid 33 byte hex string
|
/// to_vpk - valid 33 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
holder_ipk: Option<String>,
|
holder_vpk: Option<String>,
|
||||||
/// amount - amount of balance to mint
|
/// amount - amount of balance to mint
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
amount: u128,
|
amount: u128,
|
||||||
@ -160,10 +160,10 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
|||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
to_npk,
|
to_npk,
|
||||||
to_ipk,
|
to_vpk,
|
||||||
amount,
|
amount,
|
||||||
} => {
|
} => {
|
||||||
let underlying_subcommand = match (to, to_npk, to_ipk) {
|
let underlying_subcommand = match (to, to_npk, to_vpk) {
|
||||||
(None, None, None) => {
|
(None, None, None) => {
|
||||||
anyhow::bail!(
|
anyhow::bail!(
|
||||||
"Provide either account account_id of receiver or their public keys"
|
"Provide either account account_id of receiver or their public keys"
|
||||||
@ -220,7 +220,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(None, Some(to_npk), Some(to_ipk)) => {
|
(None, Some(to_npk), Some(to_vpk)) => {
|
||||||
let (from, from_privacy) = parse_addr_with_privacy_prefix(&from)?;
|
let (from, from_privacy) = parse_addr_with_privacy_prefix(&from)?;
|
||||||
|
|
||||||
match from_privacy {
|
match from_privacy {
|
||||||
@ -228,7 +228,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
|||||||
TokenProgramSubcommandPrivate::TransferTokenPrivateForeign {
|
TokenProgramSubcommandPrivate::TransferTokenPrivateForeign {
|
||||||
sender_account_id: from,
|
sender_account_id: from,
|
||||||
recipient_npk: to_npk,
|
recipient_npk: to_npk,
|
||||||
recipient_ipk: to_ipk,
|
recipient_vpk: to_vpk,
|
||||||
balance_to_move: amount,
|
balance_to_move: amount,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -236,7 +236,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
|||||||
TokenProgramSubcommandShielded::TransferTokenShieldedForeign {
|
TokenProgramSubcommandShielded::TransferTokenShieldedForeign {
|
||||||
sender_account_id: from,
|
sender_account_id: from,
|
||||||
recipient_npk: to_npk,
|
recipient_npk: to_npk,
|
||||||
recipient_ipk: to_ipk,
|
recipient_vpk: to_vpk,
|
||||||
balance_to_move: amount,
|
balance_to_move: amount,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -302,10 +302,10 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
|||||||
definition,
|
definition,
|
||||||
holder,
|
holder,
|
||||||
holder_npk,
|
holder_npk,
|
||||||
holder_ipk,
|
holder_vpk,
|
||||||
amount,
|
amount,
|
||||||
} => {
|
} => {
|
||||||
let underlying_subcommand = match (holder, holder_npk, holder_ipk) {
|
let underlying_subcommand = match (holder, holder_npk, holder_vpk) {
|
||||||
(None, None, None) => {
|
(None, None, None) => {
|
||||||
anyhow::bail!(
|
anyhow::bail!(
|
||||||
"Provide either account account_id of holder or their public keys"
|
"Provide either account account_id of holder or their public keys"
|
||||||
@ -363,7 +363,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(None, Some(holder_npk), Some(holder_ipk)) => {
|
(None, Some(holder_npk), Some(holder_vpk)) => {
|
||||||
let (definition, definition_privacy) =
|
let (definition, definition_privacy) =
|
||||||
parse_addr_with_privacy_prefix(&definition)?;
|
parse_addr_with_privacy_prefix(&definition)?;
|
||||||
|
|
||||||
@ -372,7 +372,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
|||||||
TokenProgramSubcommandPrivate::MintTokenPrivateForeign {
|
TokenProgramSubcommandPrivate::MintTokenPrivateForeign {
|
||||||
definition_account_id: definition,
|
definition_account_id: definition,
|
||||||
holder_npk,
|
holder_npk,
|
||||||
holder_ipk,
|
holder_vpk,
|
||||||
amount,
|
amount,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -380,7 +380,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
|||||||
TokenProgramSubcommandShielded::MintTokenShieldedForeign {
|
TokenProgramSubcommandShielded::MintTokenShieldedForeign {
|
||||||
definition_account_id: definition,
|
definition_account_id: definition,
|
||||||
holder_npk,
|
holder_npk,
|
||||||
holder_ipk,
|
holder_vpk,
|
||||||
amount,
|
amount,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -465,9 +465,9 @@ pub enum TokenProgramSubcommandPrivate {
|
|||||||
/// recipient_npk - valid 32 byte hex string
|
/// recipient_npk - valid 32 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
recipient_npk: String,
|
recipient_npk: String,
|
||||||
/// recipient_ipk - valid 33 byte hex string
|
/// recipient_vpk - valid 33 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
recipient_ipk: String,
|
recipient_vpk: String,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
balance_to_move: u128,
|
balance_to_move: u128,
|
||||||
},
|
},
|
||||||
@ -496,7 +496,7 @@ pub enum TokenProgramSubcommandPrivate {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
holder_npk: String,
|
holder_npk: String,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
holder_ipk: String,
|
holder_vpk: String,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
amount: u128,
|
amount: u128,
|
||||||
},
|
},
|
||||||
@ -553,9 +553,9 @@ pub enum TokenProgramSubcommandShielded {
|
|||||||
/// recipient_npk - valid 32 byte hex string
|
/// recipient_npk - valid 32 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
recipient_npk: String,
|
recipient_npk: String,
|
||||||
/// recipient_ipk - valid 33 byte hex string
|
/// recipient_vpk - valid 33 byte hex string
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
recipient_ipk: String,
|
recipient_vpk: String,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
balance_to_move: u128,
|
balance_to_move: u128,
|
||||||
},
|
},
|
||||||
@ -584,7 +584,7 @@ pub enum TokenProgramSubcommandShielded {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
holder_npk: String,
|
holder_npk: String,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
holder_ipk: String,
|
holder_vpk: String,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
amount: u128,
|
amount: u128,
|
||||||
},
|
},
|
||||||
@ -745,7 +745,7 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
|||||||
TokenProgramSubcommandPrivate::TransferTokenPrivateForeign {
|
TokenProgramSubcommandPrivate::TransferTokenPrivateForeign {
|
||||||
sender_account_id,
|
sender_account_id,
|
||||||
recipient_npk,
|
recipient_npk,
|
||||||
recipient_ipk,
|
recipient_vpk,
|
||||||
balance_to_move,
|
balance_to_move,
|
||||||
} => {
|
} => {
|
||||||
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
||||||
@ -754,18 +754,18 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
|||||||
recipient_npk.copy_from_slice(&recipient_npk_res);
|
recipient_npk.copy_from_slice(&recipient_npk_res);
|
||||||
let recipient_npk = nssa_core::NullifierPublicKey(recipient_npk);
|
let recipient_npk = nssa_core::NullifierPublicKey(recipient_npk);
|
||||||
|
|
||||||
let recipient_ipk_res = hex::decode(recipient_ipk)?;
|
let recipient_vpk_res = hex::decode(recipient_vpk)?;
|
||||||
let mut recipient_ipk = [0u8; 33];
|
let mut recipient_vpk = [0u8; 33];
|
||||||
recipient_ipk.copy_from_slice(&recipient_ipk_res);
|
recipient_vpk.copy_from_slice(&recipient_vpk_res);
|
||||||
let recipient_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
let recipient_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||||
recipient_ipk.to_vec(),
|
recipient_vpk.to_vec(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (res, [secret_sender, _]) = Token(wallet_core)
|
let (res, [secret_sender, _]) = Token(wallet_core)
|
||||||
.send_transfer_transaction_private_foreign_account(
|
.send_transfer_transaction_private_foreign_account(
|
||||||
sender_account_id,
|
sender_account_id,
|
||||||
recipient_npk,
|
recipient_npk,
|
||||||
recipient_ipk,
|
recipient_vpk,
|
||||||
balance_to_move,
|
balance_to_move,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -865,7 +865,7 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
|||||||
TokenProgramSubcommandPrivate::MintTokenPrivateForeign {
|
TokenProgramSubcommandPrivate::MintTokenPrivateForeign {
|
||||||
definition_account_id,
|
definition_account_id,
|
||||||
holder_npk,
|
holder_npk,
|
||||||
holder_ipk,
|
holder_vpk,
|
||||||
amount,
|
amount,
|
||||||
} => {
|
} => {
|
||||||
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
|
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
|
||||||
@ -875,18 +875,18 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
|||||||
holder_npk.copy_from_slice(&holder_npk_res);
|
holder_npk.copy_from_slice(&holder_npk_res);
|
||||||
let holder_npk = nssa_core::NullifierPublicKey(holder_npk);
|
let holder_npk = nssa_core::NullifierPublicKey(holder_npk);
|
||||||
|
|
||||||
let holder_ipk_res = hex::decode(holder_ipk)?;
|
let holder_vpk_res = hex::decode(holder_vpk)?;
|
||||||
let mut holder_ipk = [0u8; 33];
|
let mut holder_vpk = [0u8; 33];
|
||||||
holder_ipk.copy_from_slice(&holder_ipk_res);
|
holder_vpk.copy_from_slice(&holder_vpk_res);
|
||||||
let holder_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
let holder_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||||
holder_ipk.to_vec(),
|
holder_vpk.to_vec(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (res, [secret_definition, _]) = Token(wallet_core)
|
let (res, [secret_definition, _]) = Token(wallet_core)
|
||||||
.send_mint_transaction_private_foreign_account(
|
.send_mint_transaction_private_foreign_account(
|
||||||
definition_account_id,
|
definition_account_id,
|
||||||
holder_npk,
|
holder_npk,
|
||||||
holder_ipk,
|
holder_vpk,
|
||||||
amount,
|
amount,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -1034,7 +1034,7 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
|||||||
TokenProgramSubcommandShielded::TransferTokenShieldedForeign {
|
TokenProgramSubcommandShielded::TransferTokenShieldedForeign {
|
||||||
sender_account_id,
|
sender_account_id,
|
||||||
recipient_npk,
|
recipient_npk,
|
||||||
recipient_ipk,
|
recipient_vpk,
|
||||||
balance_to_move,
|
balance_to_move,
|
||||||
} => {
|
} => {
|
||||||
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
||||||
@ -1043,18 +1043,18 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
|||||||
recipient_npk.copy_from_slice(&recipient_npk_res);
|
recipient_npk.copy_from_slice(&recipient_npk_res);
|
||||||
let recipient_npk = nssa_core::NullifierPublicKey(recipient_npk);
|
let recipient_npk = nssa_core::NullifierPublicKey(recipient_npk);
|
||||||
|
|
||||||
let recipient_ipk_res = hex::decode(recipient_ipk)?;
|
let recipient_vpk_res = hex::decode(recipient_vpk)?;
|
||||||
let mut recipient_ipk = [0u8; 33];
|
let mut recipient_vpk = [0u8; 33];
|
||||||
recipient_ipk.copy_from_slice(&recipient_ipk_res);
|
recipient_vpk.copy_from_slice(&recipient_vpk_res);
|
||||||
let recipient_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
let recipient_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||||
recipient_ipk.to_vec(),
|
recipient_vpk.to_vec(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (res, _) = Token(wallet_core)
|
let (res, _) = Token(wallet_core)
|
||||||
.send_transfer_transaction_shielded_foreign_account(
|
.send_transfer_transaction_shielded_foreign_account(
|
||||||
sender_account_id,
|
sender_account_id,
|
||||||
recipient_npk,
|
recipient_npk,
|
||||||
recipient_ipk,
|
recipient_vpk,
|
||||||
balance_to_move,
|
balance_to_move,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -1177,7 +1177,7 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
|||||||
TokenProgramSubcommandShielded::MintTokenShieldedForeign {
|
TokenProgramSubcommandShielded::MintTokenShieldedForeign {
|
||||||
definition_account_id,
|
definition_account_id,
|
||||||
holder_npk,
|
holder_npk,
|
||||||
holder_ipk,
|
holder_vpk,
|
||||||
amount,
|
amount,
|
||||||
} => {
|
} => {
|
||||||
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
|
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
|
||||||
@ -1187,18 +1187,18 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
|||||||
holder_npk.copy_from_slice(&holder_npk_res);
|
holder_npk.copy_from_slice(&holder_npk_res);
|
||||||
let holder_npk = nssa_core::NullifierPublicKey(holder_npk);
|
let holder_npk = nssa_core::NullifierPublicKey(holder_npk);
|
||||||
|
|
||||||
let holder_ipk_res = hex::decode(holder_ipk)?;
|
let holder_vpk_res = hex::decode(holder_vpk)?;
|
||||||
let mut holder_ipk = [0u8; 33];
|
let mut holder_vpk = [0u8; 33];
|
||||||
holder_ipk.copy_from_slice(&holder_ipk_res);
|
holder_vpk.copy_from_slice(&holder_vpk_res);
|
||||||
let holder_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
let holder_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||||
holder_ipk.to_vec(),
|
holder_vpk.to_vec(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (res, _) = Token(wallet_core)
|
let (res, _) = Token(wallet_core)
|
||||||
.send_mint_transaction_shielded_foreign_account(
|
.send_mint_transaction_shielded_foreign_account(
|
||||||
definition_account_id,
|
definition_account_id,
|
||||||
holder_npk,
|
holder_npk,
|
||||||
holder_ipk,
|
holder_vpk,
|
||||||
amount,
|
amount,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@ -292,7 +292,7 @@ impl Default for WalletConfig {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Private": {
|
"Private": {
|
||||||
"account_id": "3oCG8gqdKLMegw4rRfyaMQvuPHpcASt7xwttsmnZLSkw",
|
"account_id": "FpdcxBrMkHWqXCBQ6FG98eYfWGY6jWZRsKNSi1FwDMxy",
|
||||||
"account": {
|
"account": {
|
||||||
"program_owner": [
|
"program_owner": [
|
||||||
0,
|
0,
|
||||||
@ -310,218 +310,151 @@ impl Default for WalletConfig {
|
|||||||
},
|
},
|
||||||
"key_chain": {
|
"key_chain": {
|
||||||
"secret_spending_key": [
|
"secret_spending_key": [
|
||||||
251,
|
239,
|
||||||
82,
|
27,
|
||||||
235,
|
159,
|
||||||
1,
|
83,
|
||||||
146,
|
199,
|
||||||
96,
|
194,
|
||||||
30,
|
132,
|
||||||
81,
|
|
||||||
162,
|
|
||||||
234,
|
|
||||||
33,
|
33,
|
||||||
15,
|
20,
|
||||||
123,
|
28,
|
||||||
129,
|
217,
|
||||||
116,
|
103,
|
||||||
0,
|
101,
|
||||||
|
57,
|
||||||
|
27,
|
||||||
|
125,
|
||||||
84,
|
84,
|
||||||
136,
|
57,
|
||||||
176,
|
19,
|
||||||
70,
|
86,
|
||||||
190,
|
98,
|
||||||
224,
|
135,
|
||||||
161,
|
161,
|
||||||
54,
|
221,
|
||||||
134,
|
108,
|
||||||
142,
|
125,
|
||||||
154,
|
152,
|
||||||
1,
|
174,
|
||||||
18,
|
161,
|
||||||
251,
|
64,
|
||||||
242,
|
16,
|
||||||
189
|
200
|
||||||
],
|
],
|
||||||
"private_key_holder": {
|
"private_key_holder": {
|
||||||
"nullifier_secret_key": [
|
"nullifier_secret_key": [
|
||||||
29,
|
71,
|
||||||
250,
|
195,
|
||||||
10,
|
|
||||||
187,
|
|
||||||
35,
|
|
||||||
123,
|
|
||||||
180,
|
|
||||||
250,
|
|
||||||
246,
|
|
||||||
97,
|
|
||||||
216,
|
|
||||||
153,
|
|
||||||
44,
|
|
||||||
156,
|
|
||||||
16,
|
16,
|
||||||
93,
|
119,
|
||||||
241,
|
0,
|
||||||
26,
|
98,
|
||||||
174,
|
35,
|
||||||
219,
|
106,
|
||||||
72,
|
|
||||||
84,
|
|
||||||
34,
|
|
||||||
247,
|
|
||||||
112,
|
|
||||||
101,
|
|
||||||
217,
|
|
||||||
243,
|
|
||||||
189,
|
|
||||||
173,
|
|
||||||
75,
|
|
||||||
20
|
|
||||||
],
|
|
||||||
"incoming_viewing_secret_key": [
|
|
||||||
251,
|
|
||||||
201,
|
|
||||||
22,
|
|
||||||
154,
|
|
||||||
100,
|
|
||||||
165,
|
|
||||||
218,
|
|
||||||
108,
|
|
||||||
163,
|
|
||||||
190,
|
|
||||||
135,
|
|
||||||
91,
|
|
||||||
145,
|
|
||||||
84,
|
|
||||||
69,
|
|
||||||
241,
|
|
||||||
46,
|
|
||||||
117,
|
|
||||||
217,
|
|
||||||
110,
|
|
||||||
197,
|
|
||||||
248,
|
|
||||||
91,
|
|
||||||
193,
|
|
||||||
14,
|
|
||||||
104,
|
|
||||||
88,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
153,
|
|
||||||
182,
|
|
||||||
158
|
|
||||||
],
|
|
||||||
"outgoing_viewing_secret_key": [
|
|
||||||
25,
|
|
||||||
67,
|
|
||||||
121,
|
|
||||||
76,
|
|
||||||
175,
|
|
||||||
100,
|
|
||||||
30,
|
|
||||||
198,
|
|
||||||
105,
|
|
||||||
123,
|
|
||||||
49,
|
|
||||||
169,
|
|
||||||
75,
|
|
||||||
178,
|
|
||||||
75,
|
|
||||||
210,
|
|
||||||
100,
|
|
||||||
143,
|
|
||||||
210,
|
|
||||||
243,
|
|
||||||
228,
|
|
||||||
243,
|
|
||||||
21,
|
|
||||||
18,
|
|
||||||
36,
|
|
||||||
84,
|
|
||||||
164,
|
|
||||||
186,
|
|
||||||
139,
|
139,
|
||||||
113,
|
82,
|
||||||
214,
|
145,
|
||||||
12
|
50,
|
||||||
|
27,
|
||||||
|
140,
|
||||||
|
206,
|
||||||
|
19,
|
||||||
|
53,
|
||||||
|
122,
|
||||||
|
166,
|
||||||
|
76,
|
||||||
|
195,
|
||||||
|
0,
|
||||||
|
16,
|
||||||
|
19,
|
||||||
|
21,
|
||||||
|
143,
|
||||||
|
155,
|
||||||
|
119,
|
||||||
|
9,
|
||||||
|
200,
|
||||||
|
81,
|
||||||
|
105
|
||||||
|
],
|
||||||
|
"viewing_secret_key": [
|
||||||
|
5,
|
||||||
|
117,
|
||||||
|
221,
|
||||||
|
27,
|
||||||
|
236,
|
||||||
|
199,
|
||||||
|
53,
|
||||||
|
22,
|
||||||
|
249,
|
||||||
|
231,
|
||||||
|
98,
|
||||||
|
147,
|
||||||
|
213,
|
||||||
|
116,
|
||||||
|
191,
|
||||||
|
82,
|
||||||
|
188,
|
||||||
|
148,
|
||||||
|
175,
|
||||||
|
98,
|
||||||
|
139,
|
||||||
|
52,
|
||||||
|
232,
|
||||||
|
249,
|
||||||
|
220,
|
||||||
|
217,
|
||||||
|
83,
|
||||||
|
58,
|
||||||
|
112,
|
||||||
|
155,
|
||||||
|
197,
|
||||||
|
196
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"nullifer_public_key": [
|
"nullifer_public_key": [
|
||||||
63,
|
|
||||||
202,
|
|
||||||
178,
|
|
||||||
231,
|
|
||||||
183,
|
|
||||||
82,
|
|
||||||
237,
|
|
||||||
212,
|
|
||||||
216,
|
|
||||||
221,
|
|
||||||
215,
|
|
||||||
255,
|
|
||||||
153,
|
|
||||||
101,
|
|
||||||
177,
|
177,
|
||||||
161,
|
|
||||||
254,
|
|
||||||
210,
|
|
||||||
128,
|
|
||||||
122,
|
|
||||||
54,
|
|
||||||
190,
|
|
||||||
230,
|
|
||||||
151,
|
|
||||||
183,
|
|
||||||
64,
|
64,
|
||||||
225,
|
|
||||||
229,
|
|
||||||
113,
|
|
||||||
1,
|
1,
|
||||||
228,
|
11,
|
||||||
97
|
87,
|
||||||
],
|
38,
|
||||||
"incoming_viewing_public_key": [
|
254,
|
||||||
3,
|
159,
|
||||||
235,
|
231,
|
||||||
139,
|
165,
|
||||||
131,
|
1,
|
||||||
237,
|
94,
|
||||||
177,
|
64,
|
||||||
122,
|
137,
|
||||||
189,
|
|
||||||
6,
|
|
||||||
177,
|
|
||||||
167,
|
|
||||||
178,
|
|
||||||
202,
|
|
||||||
117,
|
|
||||||
246,
|
|
||||||
58,
|
|
||||||
28,
|
|
||||||
65,
|
|
||||||
132,
|
|
||||||
79,
|
|
||||||
220,
|
|
||||||
139,
|
|
||||||
119,
|
|
||||||
243,
|
243,
|
||||||
187,
|
76,
|
||||||
160,
|
249,
|
||||||
212,
|
101,
|
||||||
121,
|
251,
|
||||||
61,
|
129,
|
||||||
247,
|
33,
|
||||||
116,
|
101,
|
||||||
72,
|
189,
|
||||||
205
|
30,
|
||||||
]
|
42,
|
||||||
|
11,
|
||||||
|
191,
|
||||||
|
34,
|
||||||
|
103,
|
||||||
|
186,
|
||||||
|
227,
|
||||||
|
230
|
||||||
|
],
|
||||||
|
"viewing_public_key": [
|
||||||
|
2, 69, 126, 43, 158, 209, 172, 144, 23, 185, 208, 25, 163, 166, 176, 200, 225, 251, 106, 211, 4, 199, 112, 243, 207, 144, 135, 56, 157, 167, 32, 219, 38]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Private": {
|
"Private": {
|
||||||
"account_id": "AKTcXgJ1xoynta1Ec7y6Jso1z1JQtHqd7aPQ1h9er6xX",
|
"account_id": "E8HwiTyQe4H9HK7icTvn95HQMnzx49mP9A2ddtMLpNaN",
|
||||||
"account": {
|
"account": {
|
||||||
"program_owner": [
|
"program_owner": [
|
||||||
0,
|
0,
|
||||||
@ -539,211 +472,20 @@ impl Default for WalletConfig {
|
|||||||
},
|
},
|
||||||
"key_chain": {
|
"key_chain": {
|
||||||
"secret_spending_key": [
|
"secret_spending_key": [
|
||||||
238,
|
48, 175, 124, 10, 230, 240, 166, 14, 249, 254, 157, 226, 208, 124, 122, 177, 203, 139, 192, 180, 43, 120, 55, 151, 50, 21, 113, 22, 254, 83, 148, 56],
|
||||||
171,
|
|
||||||
241,
|
|
||||||
69,
|
|
||||||
111,
|
|
||||||
217,
|
|
||||||
85,
|
|
||||||
64,
|
|
||||||
19,
|
|
||||||
82,
|
|
||||||
18,
|
|
||||||
189,
|
|
||||||
32,
|
|
||||||
91,
|
|
||||||
78,
|
|
||||||
175,
|
|
||||||
107,
|
|
||||||
7,
|
|
||||||
109,
|
|
||||||
60,
|
|
||||||
52,
|
|
||||||
44,
|
|
||||||
243,
|
|
||||||
230,
|
|
||||||
72,
|
|
||||||
244,
|
|
||||||
192,
|
|
||||||
92,
|
|
||||||
137,
|
|
||||||
33,
|
|
||||||
118,
|
|
||||||
254
|
|
||||||
],
|
|
||||||
"private_key_holder": {
|
"private_key_holder": {
|
||||||
"nullifier_secret_key": [
|
"nullifier_secret_key": [
|
||||||
25,
|
99, 82, 190, 140, 234, 10, 61, 163, 15, 211, 179, 54, 70, 166, 87, 5, 182, 68, 117, 244, 217, 23, 99, 9, 4, 177, 230, 125, 109, 91, 160, 30
|
||||||
211,
|
|
||||||
215,
|
|
||||||
119,
|
|
||||||
57,
|
|
||||||
223,
|
|
||||||
247,
|
|
||||||
37,
|
|
||||||
245,
|
|
||||||
144,
|
|
||||||
122,
|
|
||||||
29,
|
|
||||||
118,
|
|
||||||
245,
|
|
||||||
83,
|
|
||||||
228,
|
|
||||||
23,
|
|
||||||
9,
|
|
||||||
101,
|
|
||||||
120,
|
|
||||||
88,
|
|
||||||
33,
|
|
||||||
238,
|
|
||||||
207,
|
|
||||||
128,
|
|
||||||
61,
|
|
||||||
110,
|
|
||||||
2,
|
|
||||||
89,
|
|
||||||
62,
|
|
||||||
164,
|
|
||||||
13
|
|
||||||
],
|
],
|
||||||
"incoming_viewing_secret_key": [
|
"viewing_secret_key": [
|
||||||
193,
|
205, 32, 76, 251, 255, 236, 96, 119, 61, 111, 65, 100, 75, 218, 12, 22, 17, 170, 55, 226, 21, 154, 161, 34, 208, 74, 27, 1, 119, 13, 88, 128
|
||||||
181,
|
|
||||||
14,
|
|
||||||
196,
|
|
||||||
142,
|
|
||||||
84,
|
|
||||||
15,
|
|
||||||
65,
|
|
||||||
128,
|
|
||||||
101,
|
|
||||||
70,
|
|
||||||
196,
|
|
||||||
241,
|
|
||||||
47,
|
|
||||||
130,
|
|
||||||
221,
|
|
||||||
23,
|
|
||||||
146,
|
|
||||||
161,
|
|
||||||
237,
|
|
||||||
221,
|
|
||||||
40,
|
|
||||||
19,
|
|
||||||
126,
|
|
||||||
59,
|
|
||||||
15,
|
|
||||||
169,
|
|
||||||
236,
|
|
||||||
25,
|
|
||||||
105,
|
|
||||||
104,
|
|
||||||
231
|
|
||||||
],
|
|
||||||
"outgoing_viewing_secret_key": [
|
|
||||||
20,
|
|
||||||
170,
|
|
||||||
220,
|
|
||||||
108,
|
|
||||||
41,
|
|
||||||
23,
|
|
||||||
155,
|
|
||||||
217,
|
|
||||||
247,
|
|
||||||
190,
|
|
||||||
175,
|
|
||||||
168,
|
|
||||||
247,
|
|
||||||
34,
|
|
||||||
105,
|
|
||||||
134,
|
|
||||||
114,
|
|
||||||
74,
|
|
||||||
104,
|
|
||||||
91,
|
|
||||||
211,
|
|
||||||
62,
|
|
||||||
126,
|
|
||||||
13,
|
|
||||||
130,
|
|
||||||
100,
|
|
||||||
241,
|
|
||||||
214,
|
|
||||||
250,
|
|
||||||
236,
|
|
||||||
38,
|
|
||||||
150
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"nullifer_public_key": [
|
"nullifer_public_key": [
|
||||||
192,
|
32, 67, 72, 164, 106, 53, 66, 239, 141, 15, 52, 230, 136, 177, 2, 236, 207, 243, 134, 135, 210, 143, 87, 232, 215, 128, 194, 120, 113, 224, 4, 165
|
||||||
251,
|
|
||||||
166,
|
|
||||||
243,
|
|
||||||
167,
|
|
||||||
236,
|
|
||||||
84,
|
|
||||||
249,
|
|
||||||
35,
|
|
||||||
136,
|
|
||||||
130,
|
|
||||||
172,
|
|
||||||
219,
|
|
||||||
225,
|
|
||||||
161,
|
|
||||||
139,
|
|
||||||
229,
|
|
||||||
89,
|
|
||||||
243,
|
|
||||||
125,
|
|
||||||
194,
|
|
||||||
213,
|
|
||||||
209,
|
|
||||||
30,
|
|
||||||
23,
|
|
||||||
174,
|
|
||||||
100,
|
|
||||||
244,
|
|
||||||
124,
|
|
||||||
74,
|
|
||||||
140,
|
|
||||||
47
|
|
||||||
],
|
],
|
||||||
"incoming_viewing_public_key": [
|
"viewing_public_key": [
|
||||||
2,
|
2, 79, 110, 46, 203, 29, 206, 205, 18, 86, 27, 189, 104, 103, 113, 181, 110, 53, 78, 172, 11, 171, 190, 18, 126, 214, 81, 77, 192, 154, 58, 195, 238
|
||||||
181,
|
|
||||||
98,
|
|
||||||
93,
|
|
||||||
216,
|
|
||||||
241,
|
|
||||||
241,
|
|
||||||
110,
|
|
||||||
58,
|
|
||||||
198,
|
|
||||||
119,
|
|
||||||
174,
|
|
||||||
250,
|
|
||||||
184,
|
|
||||||
1,
|
|
||||||
204,
|
|
||||||
200,
|
|
||||||
173,
|
|
||||||
44,
|
|
||||||
238,
|
|
||||||
37,
|
|
||||||
247,
|
|
||||||
170,
|
|
||||||
156,
|
|
||||||
100,
|
|
||||||
254,
|
|
||||||
116,
|
|
||||||
242,
|
|
||||||
28,
|
|
||||||
183,
|
|
||||||
187,
|
|
||||||
77,
|
|
||||||
255
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -298,6 +298,8 @@ impl WalletCore {
|
|||||||
instruction_data: InstructionData,
|
instruction_data: InstructionData,
|
||||||
program: &ProgramWithDependencies,
|
program: &ProgramWithDependencies,
|
||||||
) -> Result<(SendTxResponse, Vec<SharedSecretKey>), ExecutionFailureKind> {
|
) -> Result<(SendTxResponse, Vec<SharedSecretKey>), ExecutionFailureKind> {
|
||||||
|
// TODO: handle large Err-variant properly
|
||||||
|
#[allow(clippy::result_large_err)]
|
||||||
self.send_privacy_preserving_tx_with_pre_check(accounts, instruction_data, program, |_| {
|
self.send_privacy_preserving_tx_with_pre_check(accounts, instruction_data, program, |_| {
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
@ -343,7 +345,7 @@ impl WalletCore {
|
|||||||
Vec::from_iter(acc_manager.public_account_nonces()),
|
Vec::from_iter(acc_manager.public_account_nonces()),
|
||||||
private_account_keys
|
private_account_keys
|
||||||
.iter()
|
.iter()
|
||||||
.map(|keys| (keys.npk.clone(), keys.ipk.clone(), keys.epk.clone()))
|
.map(|keys| (keys.npk.clone(), keys.vpk.clone(), keys.epk.clone()))
|
||||||
.collect(),
|
.collect(),
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
@ -427,7 +429,7 @@ impl WalletCore {
|
|||||||
.flat_map(|(acc_account_id, key_chain)| {
|
.flat_map(|(acc_account_id, key_chain)| {
|
||||||
let view_tag = EncryptedAccountData::compute_view_tag(
|
let view_tag = EncryptedAccountData::compute_view_tag(
|
||||||
key_chain.nullifer_public_key.clone(),
|
key_chain.nullifer_public_key.clone(),
|
||||||
key_chain.incoming_viewing_public_key.clone(),
|
key_chain.viewing_public_key.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
tx.message()
|
tx.message()
|
||||||
|
|||||||
@ -36,7 +36,7 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: winner_nsk,
|
nsk: winner_nsk,
|
||||||
npk: winner_npk,
|
npk: winner_npk,
|
||||||
ipk: winner_ipk,
|
vpk: winner_vpk,
|
||||||
auth_acc: winner_pre,
|
auth_acc: winner_pre,
|
||||||
proof: _,
|
proof: _,
|
||||||
} = self
|
} = self
|
||||||
@ -50,7 +50,7 @@ impl WalletCore {
|
|||||||
let pinata_pre = AccountWithMetadata::new(pinata_acc.clone(), false, pinata_account_id);
|
let pinata_pre = AccountWithMetadata::new(pinata_acc.clone(), false, pinata_account_id);
|
||||||
|
|
||||||
let eph_holder_winner = EphemeralKeyHolder::new(&winner_npk);
|
let eph_holder_winner = EphemeralKeyHolder::new(&winner_npk);
|
||||||
let shared_secret_winner = eph_holder_winner.calculate_shared_secret_sender(&winner_ipk);
|
let shared_secret_winner = eph_holder_winner.calculate_shared_secret_sender(&winner_vpk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
&[pinata_pre, winner_pre],
|
&[pinata_pre, winner_pre],
|
||||||
@ -70,7 +70,7 @@ impl WalletCore {
|
|||||||
vec![],
|
vec![],
|
||||||
vec![(
|
vec![(
|
||||||
winner_npk.clone(),
|
winner_npk.clone(),
|
||||||
winner_ipk.clone(),
|
winner_vpk.clone(),
|
||||||
eph_holder_winner.generate_ephemeral_public_key(),
|
eph_holder_winner.generate_ephemeral_public_key(),
|
||||||
)],
|
)],
|
||||||
output,
|
output,
|
||||||
@ -103,7 +103,7 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: _,
|
nsk: _,
|
||||||
npk: winner_npk,
|
npk: winner_npk,
|
||||||
ipk: winner_ipk,
|
vpk: winner_vpk,
|
||||||
auth_acc: winner_pre,
|
auth_acc: winner_pre,
|
||||||
proof: _,
|
proof: _,
|
||||||
} = self
|
} = self
|
||||||
@ -117,7 +117,7 @@ impl WalletCore {
|
|||||||
let pinata_pre = AccountWithMetadata::new(pinata_acc.clone(), false, pinata_account_id);
|
let pinata_pre = AccountWithMetadata::new(pinata_acc.clone(), false, pinata_account_id);
|
||||||
|
|
||||||
let eph_holder_winner = EphemeralKeyHolder::new(&winner_npk);
|
let eph_holder_winner = EphemeralKeyHolder::new(&winner_npk);
|
||||||
let shared_secret_winner = eph_holder_winner.calculate_shared_secret_sender(&winner_ipk);
|
let shared_secret_winner = eph_holder_winner.calculate_shared_secret_sender(&winner_vpk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
&[pinata_pre, winner_pre],
|
&[pinata_pre, winner_pre],
|
||||||
@ -137,7 +137,7 @@ impl WalletCore {
|
|||||||
vec![],
|
vec![],
|
||||||
vec![(
|
vec![(
|
||||||
winner_npk.clone(),
|
winner_npk.clone(),
|
||||||
winner_ipk.clone(),
|
winner_vpk.clone(),
|
||||||
eph_holder_winner.generate_ephemeral_public_key(),
|
eph_holder_winner.generate_ephemeral_public_key(),
|
||||||
)],
|
)],
|
||||||
output,
|
output,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use nssa::{AccountId, PrivateKey};
|
|||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
MembershipProof, NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
|
MembershipProof, NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
|
||||||
account::{AccountWithMetadata, Nonce},
|
account::{AccountWithMetadata, Nonce},
|
||||||
encryption::{EphemeralPublicKey, IncomingViewingPublicKey},
|
encryption::{EphemeralPublicKey, ViewingPublicKey},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::WalletCore;
|
use crate::WalletCore;
|
||||||
@ -16,7 +16,7 @@ pub enum PrivacyPreservingAccount {
|
|||||||
PrivateOwned(AccountId),
|
PrivateOwned(AccountId),
|
||||||
PrivateForeign {
|
PrivateForeign {
|
||||||
npk: NullifierPublicKey,
|
npk: NullifierPublicKey,
|
||||||
ipk: IncomingViewingPublicKey,
|
vpk: ViewingPublicKey,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ impl PrivacyPreservingAccount {
|
|||||||
pub fn is_private(&self) -> bool {
|
pub fn is_private(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
&self,
|
&self,
|
||||||
Self::PrivateOwned(_) | Self::PrivateForeign { npk: _, ipk: _ }
|
Self::PrivateOwned(_) | Self::PrivateForeign { npk: _, vpk: _ }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ impl PrivacyPreservingAccount {
|
|||||||
pub struct PrivateAccountKeys {
|
pub struct PrivateAccountKeys {
|
||||||
pub npk: NullifierPublicKey,
|
pub npk: NullifierPublicKey,
|
||||||
pub ssk: SharedSecretKey,
|
pub ssk: SharedSecretKey,
|
||||||
pub ipk: IncomingViewingPublicKey,
|
pub vpk: ViewingPublicKey,
|
||||||
pub epk: EphemeralPublicKey,
|
pub epk: EphemeralPublicKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,13 +80,13 @@ impl AccountManager {
|
|||||||
|
|
||||||
(State::Private(pre), mask)
|
(State::Private(pre), mask)
|
||||||
}
|
}
|
||||||
PrivacyPreservingAccount::PrivateForeign { npk, ipk } => {
|
PrivacyPreservingAccount::PrivateForeign { npk, vpk } => {
|
||||||
let acc = nssa_core::account::Account::default();
|
let acc = nssa_core::account::Account::default();
|
||||||
let auth_acc = AccountWithMetadata::new(acc, false, &npk);
|
let auth_acc = AccountWithMetadata::new(acc, false, &npk);
|
||||||
let pre = AccountPreparedData {
|
let pre = AccountPreparedData {
|
||||||
nsk: None,
|
nsk: None,
|
||||||
npk,
|
npk,
|
||||||
ipk,
|
vpk,
|
||||||
pre_state: auth_acc,
|
pre_state: auth_acc,
|
||||||
proof: None,
|
proof: None,
|
||||||
};
|
};
|
||||||
@ -138,8 +138,8 @@ impl AccountManager {
|
|||||||
|
|
||||||
Some(PrivateAccountKeys {
|
Some(PrivateAccountKeys {
|
||||||
npk: pre.npk.clone(),
|
npk: pre.npk.clone(),
|
||||||
ssk: eph_holder.calculate_shared_secret_sender(&pre.ipk),
|
ssk: eph_holder.calculate_shared_secret_sender(&pre.vpk),
|
||||||
ipk: pre.ipk.clone(),
|
vpk: pre.vpk.clone(),
|
||||||
epk: eph_holder.generate_ephemeral_public_key(),
|
epk: eph_holder.generate_ephemeral_public_key(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -192,7 +192,7 @@ impl AccountManager {
|
|||||||
struct AccountPreparedData {
|
struct AccountPreparedData {
|
||||||
nsk: Option<NullifierSecretKey>,
|
nsk: Option<NullifierSecretKey>,
|
||||||
npk: NullifierPublicKey,
|
npk: NullifierPublicKey,
|
||||||
ipk: IncomingViewingPublicKey,
|
vpk: ViewingPublicKey,
|
||||||
pre_state: AccountWithMetadata,
|
pre_state: AccountWithMetadata,
|
||||||
proof: Option<MembershipProof>,
|
proof: Option<MembershipProof>,
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ async fn private_acc_preparation(
|
|||||||
let nsk = from_keys.private_key_holder.nullifier_secret_key;
|
let nsk = from_keys.private_key_holder.nullifier_secret_key;
|
||||||
|
|
||||||
let from_npk = from_keys.nullifer_public_key;
|
let from_npk = from_keys.nullifer_public_key;
|
||||||
let from_ipk = from_keys.incoming_viewing_public_key;
|
let from_vpk = from_keys.viewing_public_key;
|
||||||
|
|
||||||
// TODO: Remove this unwrap, error types must be compatible
|
// TODO: Remove this unwrap, error types must be compatible
|
||||||
let proof = wallet
|
let proof = wallet
|
||||||
@ -228,7 +228,7 @@ async fn private_acc_preparation(
|
|||||||
Ok(AccountPreparedData {
|
Ok(AccountPreparedData {
|
||||||
nsk: Some(nsk),
|
nsk: Some(nsk),
|
||||||
npk: from_npk,
|
npk: from_npk,
|
||||||
ipk: from_ipk,
|
vpk: from_vpk,
|
||||||
pre_state: sender_pre,
|
pre_state: sender_pre,
|
||||||
proof,
|
proof,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -20,6 +20,9 @@ fn auth_transfer_preparation(
|
|||||||
) {
|
) {
|
||||||
let instruction_data = Program::serialize_instruction(balance_to_move).unwrap();
|
let instruction_data = Program::serialize_instruction(balance_to_move).unwrap();
|
||||||
let program = Program::authenticated_transfer_program();
|
let program = Program::authenticated_transfer_program();
|
||||||
|
|
||||||
|
// TODO: handle large Err-variant properly
|
||||||
|
#[allow(clippy::result_large_err)]
|
||||||
let tx_pre_check = move |accounts: &[&Account]| {
|
let tx_pre_check = move |accounts: &[&Account]| {
|
||||||
let from = accounts[0];
|
let from = accounts[0];
|
||||||
if from.balance >= balance_to_move {
|
if from.balance >= balance_to_move {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::vec;
|
|||||||
|
|
||||||
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
||||||
use nssa::{AccountId, program::Program};
|
use nssa::{AccountId, program::Program};
|
||||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
|
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::ViewingPublicKey};
|
||||||
|
|
||||||
use super::{NativeTokenTransfer, auth_transfer_preparation};
|
use super::{NativeTokenTransfer, auth_transfer_preparation};
|
||||||
use crate::PrivacyPreservingAccount;
|
use crate::PrivacyPreservingAccount;
|
||||||
@ -32,7 +32,7 @@ impl NativeTokenTransfer<'_> {
|
|||||||
&self,
|
&self,
|
||||||
from: AccountId,
|
from: AccountId,
|
||||||
to_npk: NullifierPublicKey,
|
to_npk: NullifierPublicKey,
|
||||||
to_ipk: IncomingViewingPublicKey,
|
to_vpk: ViewingPublicKey,
|
||||||
balance_to_move: u128,
|
balance_to_move: u128,
|
||||||
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
||||||
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
||||||
@ -43,7 +43,7 @@ impl NativeTokenTransfer<'_> {
|
|||||||
PrivacyPreservingAccount::PrivateOwned(from),
|
PrivacyPreservingAccount::PrivateOwned(from),
|
||||||
PrivacyPreservingAccount::PrivateForeign {
|
PrivacyPreservingAccount::PrivateForeign {
|
||||||
npk: to_npk,
|
npk: to_npk,
|
||||||
ipk: to_ipk,
|
vpk: to_vpk,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
instruction_data,
|
instruction_data,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
||||||
use nssa::AccountId;
|
use nssa::AccountId;
|
||||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
|
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::ViewingPublicKey};
|
||||||
|
|
||||||
use super::{NativeTokenTransfer, auth_transfer_preparation};
|
use super::{NativeTokenTransfer, auth_transfer_preparation};
|
||||||
use crate::PrivacyPreservingAccount;
|
use crate::PrivacyPreservingAccount;
|
||||||
@ -38,7 +38,7 @@ impl NativeTokenTransfer<'_> {
|
|||||||
&self,
|
&self,
|
||||||
from: AccountId,
|
from: AccountId,
|
||||||
to_npk: NullifierPublicKey,
|
to_npk: NullifierPublicKey,
|
||||||
to_ipk: IncomingViewingPublicKey,
|
to_vpk: ViewingPublicKey,
|
||||||
balance_to_move: u128,
|
balance_to_move: u128,
|
||||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||||
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
||||||
@ -49,7 +49,7 @@ impl NativeTokenTransfer<'_> {
|
|||||||
PrivacyPreservingAccount::Public(from),
|
PrivacyPreservingAccount::Public(from),
|
||||||
PrivacyPreservingAccount::PrivateForeign {
|
PrivacyPreservingAccount::PrivateForeign {
|
||||||
npk: to_npk,
|
npk: to_npk,
|
||||||
ipk: to_ipk,
|
vpk: to_vpk,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
instruction_data,
|
instruction_data,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
||||||
use nssa::{AccountId, program::Program};
|
use nssa::{AccountId, program::Program};
|
||||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
|
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::ViewingPublicKey};
|
||||||
use token_core::Instruction;
|
use token_core::Instruction;
|
||||||
|
|
||||||
use crate::{PrivacyPreservingAccount, WalletCore};
|
use crate::{PrivacyPreservingAccount, WalletCore};
|
||||||
@ -194,7 +194,7 @@ impl Token<'_> {
|
|||||||
&self,
|
&self,
|
||||||
sender_account_id: AccountId,
|
sender_account_id: AccountId,
|
||||||
recipient_npk: NullifierPublicKey,
|
recipient_npk: NullifierPublicKey,
|
||||||
recipient_ipk: IncomingViewingPublicKey,
|
recipient_vpk: ViewingPublicKey,
|
||||||
amount: u128,
|
amount: u128,
|
||||||
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
||||||
let instruction = Instruction::Transfer {
|
let instruction = Instruction::Transfer {
|
||||||
@ -209,7 +209,7 @@ impl Token<'_> {
|
|||||||
PrivacyPreservingAccount::PrivateOwned(sender_account_id),
|
PrivacyPreservingAccount::PrivateOwned(sender_account_id),
|
||||||
PrivacyPreservingAccount::PrivateForeign {
|
PrivacyPreservingAccount::PrivateForeign {
|
||||||
npk: recipient_npk,
|
npk: recipient_npk,
|
||||||
ipk: recipient_ipk,
|
vpk: recipient_vpk,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
instruction_data,
|
instruction_data,
|
||||||
@ -290,7 +290,7 @@ impl Token<'_> {
|
|||||||
&self,
|
&self,
|
||||||
sender_account_id: AccountId,
|
sender_account_id: AccountId,
|
||||||
recipient_npk: NullifierPublicKey,
|
recipient_npk: NullifierPublicKey,
|
||||||
recipient_ipk: IncomingViewingPublicKey,
|
recipient_vpk: ViewingPublicKey,
|
||||||
amount: u128,
|
amount: u128,
|
||||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||||
let instruction = Instruction::Transfer {
|
let instruction = Instruction::Transfer {
|
||||||
@ -305,7 +305,7 @@ impl Token<'_> {
|
|||||||
PrivacyPreservingAccount::Public(sender_account_id),
|
PrivacyPreservingAccount::Public(sender_account_id),
|
||||||
PrivacyPreservingAccount::PrivateForeign {
|
PrivacyPreservingAccount::PrivateForeign {
|
||||||
npk: recipient_npk,
|
npk: recipient_npk,
|
||||||
ipk: recipient_ipk,
|
vpk: recipient_vpk,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
instruction_data,
|
instruction_data,
|
||||||
@ -525,7 +525,7 @@ impl Token<'_> {
|
|||||||
&self,
|
&self,
|
||||||
definition_account_id: AccountId,
|
definition_account_id: AccountId,
|
||||||
holder_npk: NullifierPublicKey,
|
holder_npk: NullifierPublicKey,
|
||||||
holder_ipk: IncomingViewingPublicKey,
|
holder_vpk: ViewingPublicKey,
|
||||||
amount: u128,
|
amount: u128,
|
||||||
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
||||||
let instruction = Instruction::Mint {
|
let instruction = Instruction::Mint {
|
||||||
@ -540,7 +540,7 @@ impl Token<'_> {
|
|||||||
PrivacyPreservingAccount::PrivateOwned(definition_account_id),
|
PrivacyPreservingAccount::PrivateOwned(definition_account_id),
|
||||||
PrivacyPreservingAccount::PrivateForeign {
|
PrivacyPreservingAccount::PrivateForeign {
|
||||||
npk: holder_npk,
|
npk: holder_npk,
|
||||||
ipk: holder_ipk,
|
vpk: holder_vpk,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
instruction_data,
|
instruction_data,
|
||||||
@ -621,7 +621,7 @@ impl Token<'_> {
|
|||||||
&self,
|
&self,
|
||||||
definition_account_id: AccountId,
|
definition_account_id: AccountId,
|
||||||
holder_npk: NullifierPublicKey,
|
holder_npk: NullifierPublicKey,
|
||||||
holder_ipk: IncomingViewingPublicKey,
|
holder_vpk: ViewingPublicKey,
|
||||||
amount: u128,
|
amount: u128,
|
||||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||||
let instruction = Instruction::Mint {
|
let instruction = Instruction::Mint {
|
||||||
@ -636,7 +636,7 @@ impl Token<'_> {
|
|||||||
PrivacyPreservingAccount::Public(definition_account_id),
|
PrivacyPreservingAccount::Public(definition_account_id),
|
||||||
PrivacyPreservingAccount::PrivateForeign {
|
PrivacyPreservingAccount::PrivateForeign {
|
||||||
npk: holder_npk,
|
npk: holder_npk,
|
||||||
ipk: holder_ipk,
|
vpk: holder_vpk,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
instruction_data,
|
instruction_data,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use nssa::{
|
|||||||
};
|
};
|
||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
Commitment, MembershipProof, NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
|
Commitment, MembershipProof, NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
|
||||||
account::AccountWithMetadata, encryption::IncomingViewingPublicKey, program::InstructionData,
|
account::AccountWithMetadata, encryption::ViewingPublicKey, program::InstructionData,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{WalletCore, helperfunctions::produce_random_nonces};
|
use crate::{WalletCore, helperfunctions::produce_random_nonces};
|
||||||
@ -15,7 +15,7 @@ use crate::{WalletCore, helperfunctions::produce_random_nonces};
|
|||||||
pub(crate) struct AccountPreparedData {
|
pub(crate) struct AccountPreparedData {
|
||||||
pub nsk: Option<NullifierSecretKey>,
|
pub nsk: Option<NullifierSecretKey>,
|
||||||
pub npk: NullifierPublicKey,
|
pub npk: NullifierPublicKey,
|
||||||
pub ipk: IncomingViewingPublicKey,
|
pub vpk: ViewingPublicKey,
|
||||||
pub auth_acc: AccountWithMetadata,
|
pub auth_acc: AccountWithMetadata,
|
||||||
pub proof: Option<MembershipProof>,
|
pub proof: Option<MembershipProof>,
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ impl WalletCore {
|
|||||||
let mut proof = None;
|
let mut proof = None;
|
||||||
|
|
||||||
let from_npk = from_keys.nullifer_public_key;
|
let from_npk = from_keys.nullifer_public_key;
|
||||||
let from_ipk = from_keys.incoming_viewing_public_key;
|
let from_vpk = from_keys.viewing_public_key;
|
||||||
|
|
||||||
let sender_commitment = Commitment::new(&from_npk, &from_acc);
|
let sender_commitment = Commitment::new(&from_npk, &from_acc);
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ impl WalletCore {
|
|||||||
Ok(AccountPreparedData {
|
Ok(AccountPreparedData {
|
||||||
nsk,
|
nsk,
|
||||||
npk: from_npk,
|
npk: from_npk,
|
||||||
ipk: from_ipk,
|
vpk: from_vpk,
|
||||||
auth_acc: sender_pre,
|
auth_acc: sender_pre,
|
||||||
proof,
|
proof,
|
||||||
})
|
})
|
||||||
@ -79,7 +79,7 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: from_nsk,
|
nsk: from_nsk,
|
||||||
npk: from_npk,
|
npk: from_npk,
|
||||||
ipk: from_ipk,
|
vpk: from_vpk,
|
||||||
auth_acc: sender_pre,
|
auth_acc: sender_pre,
|
||||||
proof: from_proof,
|
proof: from_proof,
|
||||||
} = self.private_acc_preparation(from, true, true).await?;
|
} = self.private_acc_preparation(from, true, true).await?;
|
||||||
@ -87,7 +87,7 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: to_nsk,
|
nsk: to_nsk,
|
||||||
npk: to_npk,
|
npk: to_npk,
|
||||||
ipk: to_ipk,
|
vpk: to_vpk,
|
||||||
auth_acc: recipient_pre,
|
auth_acc: recipient_pre,
|
||||||
proof: _,
|
proof: _,
|
||||||
} = self.private_acc_preparation(to, true, false).await?;
|
} = self.private_acc_preparation(to, true, false).await?;
|
||||||
@ -95,10 +95,10 @@ impl WalletCore {
|
|||||||
tx_pre_check(&sender_pre.account, &recipient_pre.account)?;
|
tx_pre_check(&sender_pre.account, &recipient_pre.account)?;
|
||||||
|
|
||||||
let eph_holder_from = EphemeralKeyHolder::new(&from_npk);
|
let eph_holder_from = EphemeralKeyHolder::new(&from_npk);
|
||||||
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_ipk);
|
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_vpk);
|
||||||
|
|
||||||
let eph_holder_to = EphemeralKeyHolder::new(&to_npk);
|
let eph_holder_to = EphemeralKeyHolder::new(&to_npk);
|
||||||
let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_ipk);
|
let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_vpk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
&[sender_pre, recipient_pre],
|
&[sender_pre, recipient_pre],
|
||||||
@ -123,12 +123,12 @@ impl WalletCore {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
from_npk.clone(),
|
from_npk.clone(),
|
||||||
from_ipk.clone(),
|
from_vpk.clone(),
|
||||||
eph_holder_from.generate_ephemeral_public_key(),
|
eph_holder_from.generate_ephemeral_public_key(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
to_npk.clone(),
|
to_npk.clone(),
|
||||||
to_ipk.clone(),
|
to_vpk.clone(),
|
||||||
eph_holder_to.generate_ephemeral_public_key(),
|
eph_holder_to.generate_ephemeral_public_key(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -156,7 +156,7 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: from_nsk,
|
nsk: from_nsk,
|
||||||
npk: from_npk,
|
npk: from_npk,
|
||||||
ipk: from_ipk,
|
vpk: from_vpk,
|
||||||
auth_acc: sender_pre,
|
auth_acc: sender_pre,
|
||||||
proof: from_proof,
|
proof: from_proof,
|
||||||
} = self.private_acc_preparation(from, true, true).await?;
|
} = self.private_acc_preparation(from, true, true).await?;
|
||||||
@ -164,7 +164,7 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: _,
|
nsk: _,
|
||||||
npk: to_npk,
|
npk: to_npk,
|
||||||
ipk: to_ipk,
|
vpk: to_vpk,
|
||||||
auth_acc: recipient_pre,
|
auth_acc: recipient_pre,
|
||||||
proof: _,
|
proof: _,
|
||||||
} = self.private_acc_preparation(to, false, false).await?;
|
} = self.private_acc_preparation(to, false, false).await?;
|
||||||
@ -172,10 +172,10 @@ impl WalletCore {
|
|||||||
tx_pre_check(&sender_pre.account, &recipient_pre.account)?;
|
tx_pre_check(&sender_pre.account, &recipient_pre.account)?;
|
||||||
|
|
||||||
let eph_holder_from = EphemeralKeyHolder::new(&from_npk);
|
let eph_holder_from = EphemeralKeyHolder::new(&from_npk);
|
||||||
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_ipk);
|
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_vpk);
|
||||||
|
|
||||||
let eph_holder_to = EphemeralKeyHolder::new(&to_npk);
|
let eph_holder_to = EphemeralKeyHolder::new(&to_npk);
|
||||||
let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_ipk);
|
let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_vpk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
&[sender_pre, recipient_pre],
|
&[sender_pre, recipient_pre],
|
||||||
@ -197,12 +197,12 @@ impl WalletCore {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
from_npk.clone(),
|
from_npk.clone(),
|
||||||
from_ipk.clone(),
|
from_vpk.clone(),
|
||||||
eph_holder_from.generate_ephemeral_public_key(),
|
eph_holder_from.generate_ephemeral_public_key(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
to_npk.clone(),
|
to_npk.clone(),
|
||||||
to_ipk.clone(),
|
to_vpk.clone(),
|
||||||
eph_holder_to.generate_ephemeral_public_key(),
|
eph_holder_to.generate_ephemeral_public_key(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -223,7 +223,7 @@ impl WalletCore {
|
|||||||
&self,
|
&self,
|
||||||
from: AccountId,
|
from: AccountId,
|
||||||
to_npk: NullifierPublicKey,
|
to_npk: NullifierPublicKey,
|
||||||
to_ipk: IncomingViewingPublicKey,
|
to_vpk: ViewingPublicKey,
|
||||||
instruction_data: InstructionData,
|
instruction_data: InstructionData,
|
||||||
tx_pre_check: impl FnOnce(&Account, &Account) -> Result<(), ExecutionFailureKind>,
|
tx_pre_check: impl FnOnce(&Account, &Account) -> Result<(), ExecutionFailureKind>,
|
||||||
program: Program,
|
program: Program,
|
||||||
@ -231,7 +231,7 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: from_nsk,
|
nsk: from_nsk,
|
||||||
npk: from_npk,
|
npk: from_npk,
|
||||||
ipk: from_ipk,
|
vpk: from_vpk,
|
||||||
auth_acc: sender_pre,
|
auth_acc: sender_pre,
|
||||||
proof: from_proof,
|
proof: from_proof,
|
||||||
} = self.private_acc_preparation(from, true, true).await?;
|
} = self.private_acc_preparation(from, true, true).await?;
|
||||||
@ -244,8 +244,8 @@ impl WalletCore {
|
|||||||
|
|
||||||
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
||||||
|
|
||||||
let shared_secret_from = eph_holder.calculate_shared_secret_sender(&from_ipk);
|
let shared_secret_from = eph_holder.calculate_shared_secret_sender(&from_vpk);
|
||||||
let shared_secret_to = eph_holder.calculate_shared_secret_sender(&to_ipk);
|
let shared_secret_to = eph_holder.calculate_shared_secret_sender(&to_vpk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
&[sender_pre, recipient_pre],
|
&[sender_pre, recipient_pre],
|
||||||
@ -267,12 +267,12 @@ impl WalletCore {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
from_npk.clone(),
|
from_npk.clone(),
|
||||||
from_ipk.clone(),
|
from_vpk.clone(),
|
||||||
eph_holder.generate_ephemeral_public_key(),
|
eph_holder.generate_ephemeral_public_key(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
to_npk.clone(),
|
to_npk.clone(),
|
||||||
to_ipk.clone(),
|
to_vpk.clone(),
|
||||||
eph_holder.generate_ephemeral_public_key(),
|
eph_holder.generate_ephemeral_public_key(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -301,7 +301,7 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: from_nsk,
|
nsk: from_nsk,
|
||||||
npk: from_npk,
|
npk: from_npk,
|
||||||
ipk: from_ipk,
|
vpk: from_vpk,
|
||||||
auth_acc: sender_pre,
|
auth_acc: sender_pre,
|
||||||
proof: from_proof,
|
proof: from_proof,
|
||||||
} = self.private_acc_preparation(from, true, true).await?;
|
} = self.private_acc_preparation(from, true, true).await?;
|
||||||
@ -315,7 +315,7 @@ impl WalletCore {
|
|||||||
let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, to);
|
let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, to);
|
||||||
|
|
||||||
let eph_holder = EphemeralKeyHolder::new(&from_npk);
|
let eph_holder = EphemeralKeyHolder::new(&from_npk);
|
||||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&from_ipk);
|
let shared_secret = eph_holder.calculate_shared_secret_sender(&from_vpk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
&[sender_pre, recipient_pre],
|
&[sender_pre, recipient_pre],
|
||||||
@ -333,7 +333,7 @@ impl WalletCore {
|
|||||||
vec![],
|
vec![],
|
||||||
vec![(
|
vec![(
|
||||||
from_npk.clone(),
|
from_npk.clone(),
|
||||||
from_ipk.clone(),
|
from_vpk.clone(),
|
||||||
eph_holder.generate_ephemeral_public_key(),
|
eph_holder.generate_ephemeral_public_key(),
|
||||||
)],
|
)],
|
||||||
output,
|
output,
|
||||||
@ -366,7 +366,7 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: to_nsk,
|
nsk: to_nsk,
|
||||||
npk: to_npk,
|
npk: to_npk,
|
||||||
ipk: to_ipk,
|
vpk: to_vpk,
|
||||||
auth_acc: recipient_pre,
|
auth_acc: recipient_pre,
|
||||||
proof: _,
|
proof: _,
|
||||||
} = self.private_acc_preparation(to, true, false).await?;
|
} = self.private_acc_preparation(to, true, false).await?;
|
||||||
@ -376,7 +376,7 @@ impl WalletCore {
|
|||||||
let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, from);
|
let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, from);
|
||||||
|
|
||||||
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
||||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk);
|
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_vpk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
&[sender_pre, recipient_pre],
|
&[sender_pre, recipient_pre],
|
||||||
@ -394,7 +394,7 @@ impl WalletCore {
|
|||||||
vec![from_acc.nonce],
|
vec![from_acc.nonce],
|
||||||
vec![(
|
vec![(
|
||||||
to_npk.clone(),
|
to_npk.clone(),
|
||||||
to_ipk.clone(),
|
to_vpk.clone(),
|
||||||
eph_holder.generate_ephemeral_public_key(),
|
eph_holder.generate_ephemeral_public_key(),
|
||||||
)],
|
)],
|
||||||
output,
|
output,
|
||||||
@ -432,7 +432,7 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: _,
|
nsk: _,
|
||||||
npk: to_npk,
|
npk: to_npk,
|
||||||
ipk: to_ipk,
|
vpk: to_vpk,
|
||||||
auth_acc: recipient_pre,
|
auth_acc: recipient_pre,
|
||||||
proof: _,
|
proof: _,
|
||||||
} = self.private_acc_preparation(to, false, false).await?;
|
} = self.private_acc_preparation(to, false, false).await?;
|
||||||
@ -442,7 +442,7 @@ impl WalletCore {
|
|||||||
let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, from);
|
let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, from);
|
||||||
|
|
||||||
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
||||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk);
|
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_vpk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
&[sender_pre, recipient_pre],
|
&[sender_pre, recipient_pre],
|
||||||
@ -460,7 +460,7 @@ impl WalletCore {
|
|||||||
vec![from_acc.nonce],
|
vec![from_acc.nonce],
|
||||||
vec![(
|
vec![(
|
||||||
to_npk.clone(),
|
to_npk.clone(),
|
||||||
to_ipk.clone(),
|
to_vpk.clone(),
|
||||||
eph_holder.generate_ephemeral_public_key(),
|
eph_holder.generate_ephemeral_public_key(),
|
||||||
)],
|
)],
|
||||||
output,
|
output,
|
||||||
@ -487,7 +487,7 @@ impl WalletCore {
|
|||||||
&self,
|
&self,
|
||||||
from: AccountId,
|
from: AccountId,
|
||||||
to_npk: NullifierPublicKey,
|
to_npk: NullifierPublicKey,
|
||||||
to_ipk: IncomingViewingPublicKey,
|
to_vpk: ViewingPublicKey,
|
||||||
instruction_data: InstructionData,
|
instruction_data: InstructionData,
|
||||||
tx_pre_check: impl FnOnce(&Account, &Account) -> Result<(), ExecutionFailureKind>,
|
tx_pre_check: impl FnOnce(&Account, &Account) -> Result<(), ExecutionFailureKind>,
|
||||||
program: Program,
|
program: Program,
|
||||||
@ -504,7 +504,7 @@ impl WalletCore {
|
|||||||
let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, &to_npk);
|
let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, &to_npk);
|
||||||
|
|
||||||
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
||||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk);
|
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_vpk);
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
let (output, proof) = circuit::execute_and_prove(
|
||||||
&[sender_pre, recipient_pre],
|
&[sender_pre, recipient_pre],
|
||||||
@ -522,7 +522,7 @@ impl WalletCore {
|
|||||||
vec![from_acc.nonce],
|
vec![from_acc.nonce],
|
||||||
vec![(
|
vec![(
|
||||||
to_npk.clone(),
|
to_npk.clone(),
|
||||||
to_ipk.clone(),
|
to_vpk.clone(),
|
||||||
eph_holder.generate_ephemeral_public_key(),
|
eph_holder.generate_ephemeral_public_key(),
|
||||||
)],
|
)],
|
||||||
output,
|
output,
|
||||||
@ -548,13 +548,13 @@ impl WalletCore {
|
|||||||
let AccountPreparedData {
|
let AccountPreparedData {
|
||||||
nsk: _,
|
nsk: _,
|
||||||
npk: from_npk,
|
npk: from_npk,
|
||||||
ipk: from_ipk,
|
vpk: from_vpk,
|
||||||
auth_acc: sender_pre,
|
auth_acc: sender_pre,
|
||||||
proof: _,
|
proof: _,
|
||||||
} = self.private_acc_preparation(from, false, false).await?;
|
} = self.private_acc_preparation(from, false, false).await?;
|
||||||
|
|
||||||
let eph_holder_from = EphemeralKeyHolder::new(&from_npk);
|
let eph_holder_from = EphemeralKeyHolder::new(&from_npk);
|
||||||
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_ipk);
|
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_vpk);
|
||||||
|
|
||||||
let instruction: u128 = 0;
|
let instruction: u128 = 0;
|
||||||
|
|
||||||
@ -574,7 +574,7 @@ impl WalletCore {
|
|||||||
vec![],
|
vec![],
|
||||||
vec![(
|
vec![(
|
||||||
from_npk.clone(),
|
from_npk.clone(),
|
||||||
from_ipk.clone(),
|
from_vpk.clone(),
|
||||||
eph_holder_from.generate_ephemeral_public_key(),
|
eph_holder_from.generate_ephemeral_public_key(),
|
||||||
)],
|
)],
|
||||||
output,
|
output,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user