Provides an API that be used for private token wrapping
- Start test validator
$> make test-validator- Run tests
$> cargo testThe private-wrapper-cli can be used to start the API, and interact with the API from the command line.
To compile in debug mode
$> make binTo compile in release mode
$> make bin-releaseTo explore the CLI now run
$> ./private-wrapper-cli --helpNote: The API can be used for confidential transfers in general without needing to use the spl token wrap program
To start the API run
$> ./private-wrapper-cli start-apiDue to the lack of availability for confidential transfer sdk's in browsers, the API uses signed messages to generate AE and ElGamal keypairs.
- For ElGamal keypair generation the message to sign is
[bytes("ElGamalSecretKey"), bytes("")] - For AE keypair generation the message to sign is
[bytes("AEKey"), bytes("")]
This will need to be done only once, and involves creating the confidential token account for the wrapped token mint.
To do this send a POST request to http://example.com/confidential-balances/initialize with the following payload
authorityis the public key of the wallettoken_mintis the mint address of the confidential wrapped mintelgamal_signatureis a message signed by theauthorityfollowing the ElGamal signature from the confidential blink specae_signatureis a message signed by theauthorityfollowing the AE signature from the confidential blink spec
{
"authority": "Hsh7Fp27e3JbQQog9i1nzF6qY8fdWHTbF7RW1xzuLx5T",
"token_mint": "EFnCaHgGto1NNk6Ym7TCoxdwKF24u2CYMSzaHHJ6pbFu",
"elgamal_signature": "3Cn8oMYkFjdZVDVvtFRbn9K8hMRZ4EWoFQ4m8LTpb9VL85hHXGwqpnDTtDPmBnsugppzNF7QfWvnG8NabGWN4d2V",
"ae_signature": "47exZmEWHavGx7PXALPqjGn2qdh3dKfeqyt8Vj6amJJntdGTxuPURTKB9q4tRBgqiyosv4orjh6f6b1Cg3K8xwPk"
} The response will be an aray of bincode serialized, base64 encoded transactions that need to be parsed, and signed by the authority specified in the request.
{
"transactions": [
"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAYI+rdhoUWelWT7ijUTm1jMPw91zk0rKZJXk7AJ4U4ASVaEmsV9IxT8lBJsQolAkvEb/0PrNJa0l16F+RbrX5n0cgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqfVFxh70WY12tQEVf3CwMEkxo8hVnWl27rLXwgAAAAG3fbh7nWP3hhCXbzkbM3athr8TYO5DSf+vfko2KGL/AhjdaziruooGms3TWgbp2pTzPY4wHRVk2wF0GVAAAAAjJclj04kifG7PRApFI4NgwtaE5na/xCEBI572Nvp+FnE8Sstk7CtexH58Qe9sM3ChaKbB5Wh7wy7sOWOphbLcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAYGAAEABwIEAQEEBAEAAgADHQUABAQBBwMALxsChouPwrHzubhffjuolbzRXF2SfqQSgvdL0MVjirK1kEIY3/8GAAABAAAAAAABBQBhBDI1+sR8ND9KBgoNPEONdL3gjndURYVBiWpsjtfwdUUjGjBIFc6idcZEZImVaka/ALSVwa0VRbsX1x/fzGAF5AjF+zAs+9+CwUWUUcGayi4IxV0BVBigiG0TbKRXqxTCDg=="
]
}
Note: You must first initialize the confidential transfer account
Send a POST request to http://example.com/private-wrapper/wrap with the following payload.
authorityis the public key of the walletunwrapped_token_mintis the token mint address of the unwrapped token (ie: USDT)wrapped_token_mintis the token mint of the wrapped mint as created via the spl token wrap programunwrapped_token_programis the program id of the token program which createdunwrapped_token_mintamountis the amount of unwrapped tokens to wrap in lamports
{
"authority": "Hsh7Fp27e3JbQQog9i1nzF6qY8fdWHTbF7RW1xzuLx5T",
"unwrapped_token_mint": "GqxbzHAZrSaTGEqXcTCUiMR7bLUPrSCb4nZdqcKEkahv",
"wrapped_token_mint": "3pQjCDCmaYGriwzz2M48WKkpXhMRRu3Q2Ghss8CqxRVx",
"unwrapped_token_program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"amount": 1
} The response will be an aray of bincode serialized, base64 encoded transactions that need to be parsed, and signed by the authority specified in the request.
{
"transactions": [
"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAUK+rdhoUWelWT7ijUTm1jMPw91zk0rKZJXk7AJ4U4ASVYp3IAoVvKs3kWHTVX2guZdh94TKi96xh2jbFTp4AwQJ32hcjOVj0fIE2NxZjn5g8Ej9sw5xKvzCO9FbwV5D14UhR58BbJsU4pua/UvEGLpf6XagAmTO/OUanxFEKOh3tHFy5FYJHc8ramA2J5VQrFRGYTsZs4JGPKVScRY3i5S6wXdgsd3+OvUnXsxAnsxgWy0bep7s7JFXPAhWGSSQblsBt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKkG3fbh7nWP3hhCXbzkbM3athr8TYO5DSf+vfko2KGL/JzWcOgns5hu0S1oSXZXhQJsSb+HXpqciMwOT2Fcno/I62oNsrC8NQAUhrgMjc9nGOkIHDqNDec4jdOzqZQncXEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEFCQIBCAYHBAkDAAkBAQAAAAAAAAA="
]
} To deposit your non confidential wrapped balance into the pending confidential balance send a POST request to http://example.com/confidential-balances/deposit with the following payload
authorityis the public key of the wallettoken_mintis the mint address of the confidential wrapped mintamountis the amount of wrapped tokens in lamports to deposit
{
"authority": "Hsh7Fp27e3JbQQog9i1nzF6qY8fdWHTbF7RW1xzuLx5T",
"token_mint": "EFnCaHgGto1NNk6Ym7TCoxdwKF24u2CYMSzaHHJ6pbFu",
"amount": 1
} The response will be an aray of bincode serialized, base64 encoded transactions that need to be parsed, and signed by the authority specified in the request.
{
"transactions": [
"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIE+rdhoUWelWT7ijUTm1jMPw91zk0rKZJXk7AJ4U4ASVaEmsV9IxT8lBJsQolAkvEb/0PrNJa0l16F+RbrX5n0cgbd9uHudY/eGEJdvORszdq2GvxNg7kNJ/69+SjYoYv8xPErLZOwrXsR+fEHvbDNwoWimweVoe8Mu7DljqYWy3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECBAEDAAALGwUBAAAAAAAAAAk="
]
} To apply the pending confidential balance send a POST request to http://example.com/confidential-balances/apply with the following payload
authorityis the public key of the wallettoken_mintis the mint address of the confidential wrapped mintelgamal_signatureis a message signed by theauthorityfollowing the ElGamal signature from the confidential blink specae_signatureis a message signed by theauthorityfollowing the AE signature from the confidential blink spec
{
"authority": "Hsh7Fp27e3JbQQog9i1nzF6qY8fdWHTbF7RW1xzuLx5T",
"token_mint": "EFnCaHgGto1NNk6Ym7TCoxdwKF24u2CYMSzaHHJ6pbFu",
"elgamal_signature": "3Cn8oMYkFjdZVDVvtFRbn9K8hMRZ4EWoFQ4m8LTpb9VL85hHXGwqpnDTtDPmBnsugppzNF7QfWvnG8NabGWN4d2V",
"ae_signature": "47exZmEWHavGx7PXALPqjGn2qdh3dKfeqyt8Vj6amJJntdGTxuPURTKB9q4tRBgqiyosv4orjh6f6b1Cg3K8xwPk"
} The response will be an aray of bincode serialized, base64 encoded transactions that need to be parsed, and signed by the authority specified in the request.
{
"transactions": [
"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIE+rdhoUWelWT7ijUTm1jMPw91zk0rKZJXk7AJ4U4ASVaEmsV9IxT8lBJsQolAkvEb/0PrNJa0l16F+RbrX5n0cgbd9uHudY/eGEJdvORszdq2GvxNg7kNJ/69+SjYoYv8xPErLZOwrXsR+fEHvbDNwoWimweVoe8Mu7DljqYWy3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECBAEDAAALGwUBAAAAAAAAAAk="
]
} To get confidential and non confidential balances for the confidential wrapped mint send a POST request to http://example.com/confidential-balances/balances with the following payload
authorityis the public key of the wallettoken_mintis the mint address of the confidential wrapped mintelgamal_signatureis a message signed by theauthorityfollowing the ElGamal signature from the confidential blink specae_signatureis a message signed by theauthorityfollowing the AE signature from the confidential blink spec
{
"authority": "Hsh7Fp27e3JbQQog9i1nzF6qY8fdWHTbF7RW1xzuLx5T",
"token_mint": "EFnCaHgGto1NNk6Ym7TCoxdwKF24u2CYMSzaHHJ6pbFu",
"elgamal_signature": "3Cn8oMYkFjdZVDVvtFRbn9K8hMRZ4EWoFQ4m8LTpb9VL85hHXGwqpnDTtDPmBnsugppzNF7QfWvnG8NabGWN4d2V",
"ae_signature": "47exZmEWHavGx7PXALPqjGn2qdh3dKfeqyt8Vj6amJJntdGTxuPURTKB9q4tRBgqiyosv4orjh6f6b1Cg3K8xwPk"
} The response will be a JSON object with the following fields
pending_balanceis the confidential balance waiting to be appliedavailable_balanceis the decrypted confidential balancenon_confidential_balanceis the non confidential balance
{
"pending_balance": 0.0,
"available_balance": 1e-9,
"non_confidential_balance": 0.00001
} Note: the recipient must first initialize a confidential transfer account Note: After transferring the recipient must apply the pending balance
To transfer confidential tokens you will need to generate three temporary keypairs used to store proof state. Label the keypair as follows
equality_proof_keypairrange_proof_keypairciphertext_proof_keypair
After generating the keypairs send a POST request to http://example.com/confidential-balances/transfer with the following payload
authorityis the public key of the wallettoken_mintis the mint address of the confidential wrapped mintelgamal_signatureis a message signed by theauthorityfollowing the ElGamal signature from the confidential blink specae_signatureis a message signed by theauthorityfollowing the AE signature from the confidential blink specreceiving_token_accountwallet address of the recipient to receive the confidential tokensequality_proof_keypairThe base58 encoded private key of the equality proof keypairrange_proof_keypairThe base58 encoded private key of the range proof keypairciphertext_proof_keypairThe base58 encoded private key of the ciphertext proof keypairamountThe amount of tokens to transfer in lamports
{
"authority": "Hsh7Fp27e3JbQQog9i1nzF6qY8fdWHTbF7RW1xzuLx5T",
"token_mint": "EFnCaHgGto1NNk6Ym7TCoxdwKF24u2CYMSzaHHJ6pbFu",
"elgamal_signature": "3Cn8oMYkFjdZVDVvtFRbn9K8hMRZ4EWoFQ4m8LTpb9VL85hHXGwqpnDTtDPmBnsugppzNF7QfWvnG8NabGWN4d2V",
"ae_signature": "47exZmEWHavGx7PXALPqjGn2qdh3dKfeqyt8Vj6amJJntdGTxuPURTKB9q4tRBgqiyosv4orjh6f6b1Cg3K8xwPk",
"receiving_token_account": "AtLx7URpBXfsfnWLhxXUtngji5PnKCoR2GY3YWxQZsU9",
"equality_proof_keypair": "PVVyq6JHhZySpAfdrTjiYaGrTcYtaJ87pMvxr7KK7bDLdyFPujbFfyyDyVjmXPZyxSbthh8LLEL36fcYSDeqgGf",
"ciphertext_validity_proof_keypair": "3qYrL5FgBuPR5CJRAzvf7dk2o8J8rt8bTtMEnUo4EQ736ovymaVtbumT43SM8J1RHkVg8AqhRfvQxMHW2RVtWQ27",
"range_proof_keypair": "59ceHzjfZS1RUUg5ZVF1uxxdPo7rzWPpKZBeK5pq1aHAjSRoFohKLUKWAgCSQmtPe1B4rthTKjHyR7xAeUQXHmX6",
"amount": 1
} The response will be an aray of bincode serialized, base64 encoded transactions that need to be parsed, and signed by the authority specified in the request. The very first transaction in the array also needs to be signed by the equality_proof_keypair, range_proof_keypair and ciphertext_proof_keypair.
You must ensure that each transaction has confirmed before sending the next transaction. The very final transaction closes the equality proof, range proof, and ciphertext proof accounts refunding the rent to the authority specified in the request payload.
{
"transactions": [
"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"
]
} To withdraw confidential tokens you will need to generate two temporary keypairs used to store proof state. Label the keypair as follows
equality_proof_keypairrange_proof_keypair
After generating the keypairs send a POST request to http://example.com/confidential-balances/withdraw with the following payload
authorityis the public key of the wallettoken_mintis the mint address of the confidential wrapped mintelgamal_signatureis a message signed by theauthorityfollowing the ElGamal signature from the confidential blink specae_signatureis a message signed by theauthorityfollowing the AE signature from the confidential blink specreceiving_token_accountthe ATA of the wrapped mint for the public key you want to transfer funds tooequality_proof_keypairThe base58 encoded private key of the equality proof keypairrange_proof_keypairThe base58 encoded private key of the range proof keypairamountThe amount of tokens to withdraw from the confidential balance
{
"authority": "Hsh7Fp27e3JbQQog9i1nzF6qY8fdWHTbF7RW1xzuLx5T",
"token_mint": "EFnCaHgGto1NNk6Ym7TCoxdwKF24u2CYMSzaHHJ6pbFu",
"elgamal_signature": "3Cn8oMYkFjdZVDVvtFRbn9K8hMRZ4EWoFQ4m8LTpb9VL85hHXGwqpnDTtDPmBnsugppzNF7QfWvnG8NabGWN4d2V",
"ae_signature": "47exZmEWHavGx7PXALPqjGn2qdh3dKfeqyt8Vj6amJJntdGTxuPURTKB9q4tRBgqiyosv4orjh6f6b1Cg3K8xwPk",
"amount": 1,
"equality_proof_keypair": "4ZS9bedJkNCAgcV7fz19W8qirhMo4gBc1gQpxHLsJvadxeSFhPV12CU6YTGhL6MMWX2mzxcJpFNsySQb6t7sx3qy",
"range_proof_keypair": "EAc1zWBSFuSdtXUhMTRXiK7NdRgXBcCs1TVtyg13iDkYw9K6qnov3GBE5X11Xz3rmG8zrC6hX6MX1cmcuiYYCDi"
} The response will be an aray of bincode serialized, base64 encoded transactions that need to be parsed, and signed by the authority specified in the request. The very first transaction in the array also needs to be signed by the equality_proof_keypair, range_proof_keypair
You must ensure that each transaction has confirmed before sending the next transaction. The very final transaction closes the equality proof, and range proof accounts refunding the rent to the authority specified in the request payload.
{
"transactions": [
"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"
]
} Note: Before you unwrap tokens, you must first withdraw them from your confidential balance into your non confidential balance
Send a POST request to http://example.com/private-wrapper/unwrap with the following payload.
authorityis the public key of the walletunwrapped_token_mintis the token mint address of the unwrapped token (ie: USDT)wrapped_token_mintis the token mint of the wrapped mint as created via the spl token wrap programunwrapped_token_programis the program id of the token program which createdunwrapped_token_mintamountis the amount of unwrapped tokens to wrap in lamports
{
"authority": "Hsh7Fp27e3JbQQog9i1nzF6qY8fdWHTbF7RW1xzuLx5T",
"unwrapped_token_mint": "GqxbzHAZrSaTGEqXcTCUiMR7bLUPrSCb4nZdqcKEkahv",
"wrapped_token_mint": "3pQjCDCmaYGriwzz2M48WKkpXhMRRu3Q2Ghss8CqxRVx",
"unwrapped_token_program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"amount": 1
} The response will be an aray of bincode serialized, base64 encoded transactions that need to be parsed, and signed by the authority specified in the request.
{
"transactions": [
"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAUK+rdhoUWelWT7ijUTm1jMPw91zk0rKZJXk7AJ4U4ASVYp3IAoVvKs3kWHTVX2guZdh94TKi96xh2jbFTp4AwQJ32hcjOVj0fIE2NxZjn5g8Ej9sw5xKvzCO9FbwV5D14UhR58BbJsU4pua/UvEGLpf6XagAmTO/OUanxFEKOh3tHFy5FYJHc8ramA2J5VQrFRGYTsZs4JGPKVScRY3i5S6wXdgsd3+OvUnXsxAnsxgWy0bep7s7JFXPAhWGSSQblsBt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKkG3fbh7nWP3hhCXbzkbM3athr8TYO5DSf+vfko2KGL/JzWcOgns5hu0S1oSXZXhQJsSb+HXpqciMwOT2Fcno/I62oNsrC8NQAUhrgMjc9nGOkIHDqNDec4jdOzqZQncXEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEFCQIBCAYHBAkDAAkBAQAAAAAAAAA="
]
}