diff --git a/yarn-project/cli-wallet/src/utils/options/fees.ts b/yarn-project/cli-wallet/src/utils/options/fees.ts index c2ff52bb703a..48d36d173049 100644 --- a/yarn-project/cli-wallet/src/utils/options/fees.ts +++ b/yarn-project/cli-wallet/src/utils/options/fees.ts @@ -15,6 +15,7 @@ import { Option } from 'commander'; import type { WalletDB } from '../../storage/wallet_db.js'; import { createOrRetrieveAccount } from '../accounts.js'; +import { SponsoredFeePaymentMethod } from '../sponsored_fee_payment.js'; import { aliasedAddressParser } from './options.js'; export type CliFeeArgs = { @@ -85,13 +86,13 @@ function getFeePaymentMethodParams(allowCustomFeePayer: boolean): OptionParams { return { method: { type: 'name', - description: 'Valid values: "fee_juice", "fpc-public", "fpc-private".', + description: 'Valid values: "fee_juice", "fpc-public", "fpc-private", "fpc-sponsored"', default: 'fee_juice', }, ...(feePayer ? { feePayer } : {}), asset: { type: 'address', - description: 'The asset used for fee payment. Not required for the "fee_juice" method.', + description: 'The asset used for fee payment. Required for "fpc-public" and "fpc-private".', }, fpc: { type: 'address', @@ -260,17 +261,18 @@ export function parsePaymentMethod( return acc; }, {} as Record); - const getFpcOpts = (parsed: Record, db?: WalletDB) => { + const getFpc = () => { if (!parsed.fpc) { throw new Error('Missing "fpc" in payment option'); } + return aliasedAddressParser('contracts', parsed.fpc, db); + }; + + const getAsset = () => { if (!parsed.asset) { throw new Error('Missing "asset" in payment option'); } - - const fpc = aliasedAddressParser('contracts', parsed.fpc, db); - - return [AztecAddress.fromString(parsed.asset), fpc]; + return AztecAddress.fromString(parsed.asset); }; return async (sender: AccountWallet) => { @@ -308,17 +310,23 @@ export function parsePaymentMethod( } } case 'fpc-public': { - const [asset, fpc] = getFpcOpts(parsed, db); + const fpc = getFpc(); + const asset = getAsset(); log(`Using public fee payment with asset ${asset} via paymaster ${fpc}`); const { PublicFeePaymentMethod } = await import('@aztec/aztec.js/fee'); return new PublicFeePaymentMethod(fpc, sender); } case 'fpc-private': { - const [asset, fpc] = getFpcOpts(parsed, db); + const fpc = getFpc(); + const asset = getAsset(); log(`Using private fee payment with asset ${asset} via paymaster ${fpc}`); const { PrivateFeePaymentMethod } = await import('@aztec/aztec.js/fee'); return new PrivateFeePaymentMethod(fpc, sender); } + case 'fpc-sponsored': { + const sponsor = getFpc(); + return new SponsoredFeePaymentMethod(sponsor); + } case undefined: throw new Error('Missing "method" in payment option'); default: diff --git a/yarn-project/cli-wallet/src/utils/sponsored_fee_payment.ts b/yarn-project/cli-wallet/src/utils/sponsored_fee_payment.ts new file mode 100644 index 000000000000..45f3dd4270b6 --- /dev/null +++ b/yarn-project/cli-wallet/src/utils/sponsored_fee_payment.ts @@ -0,0 +1,29 @@ +import type { FeePaymentMethod } from '@aztec/aztec.js/fee'; +import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi'; +import { AztecAddress } from '@aztec/stdlib/aztec-address'; + +export class SponsoredFeePaymentMethod implements FeePaymentMethod { + constructor(private paymentContract: AztecAddress) {} + + getAsset(): Promise { + throw new Error('Asset is not required for sponsored fpc.'); + } + + getFeePayer() { + return Promise.resolve(this.paymentContract); + } + + async getFunctionCalls() { + return [ + { + name: 'sponsor_unconditionally', + to: this.paymentContract, + selector: await FunctionSelector.fromSignature('sponsor_unconditionally()'), + type: FunctionType.PRIVATE, + isStatic: false, + args: [], + returnTypes: [], + }, + ]; + } +} diff --git a/yarn-project/cli-wallet/test/flows/basic.sh b/yarn-project/cli-wallet/test/flows/basic.sh index f301816909ba..de95ba79a4d4 100755 --- a/yarn-project/cli-wallet/test/flows/basic.sh +++ b/yarn-project/cli-wallet/test/flows/basic.sh @@ -11,6 +11,6 @@ aztec-wallet deploy token_contract@Token --args accounts:test0 Test TST 18 -f te aztec-wallet send mint_to_public -ca last --args accounts:test0 $AMOUNT -f test0 RESULT=$(aztec-wallet simulate balance_of_public -ca last --args accounts:test0 -f test0 | grep "Simulation result:" | awk '{print $3}') -section "Test account public balance is ${RESULT}" +section "Account public balance is ${RESULT}" assert_eq ${RESULT} "${AMOUNT}n" diff --git a/yarn-project/cli-wallet/test/flows/create_account_pay_native.sh b/yarn-project/cli-wallet/test/flows/create_account_pay_native.sh index 6cac36685ab7..ca6d49eb5db0 100755 --- a/yarn-project/cli-wallet/test/flows/create_account_pay_native.sh +++ b/yarn-project/cli-wallet/test/flows/create_account_pay_native.sh @@ -4,13 +4,6 @@ source ../utils/setup.sh test_title "Create an account and deploy using native fee payment with bridging" -echo -warn //////////////////////////////////////////////////////////////// -warn // WARNING: this test requires protocol contracts to be setup // -warn // aztec setup-protocol-contracts // -warn //////////////////////////////////////////////////////////////// -echo - aztec-wallet create-account -a main --register-only aztec-wallet bridge-fee-juice 100000000000000000 main --mint --no-wait diff --git a/yarn-project/cli-wallet/test/flows/private_authwit_transfer.sh b/yarn-project/cli-wallet/test/flows/private_authwit_transfer.sh index 5acee2f91e41..1c6f9c3a0495 100755 --- a/yarn-project/cli-wallet/test/flows/private_authwit_transfer.sh +++ b/yarn-project/cli-wallet/test/flows/private_authwit_transfer.sh @@ -8,7 +8,7 @@ MINT_AMOUNT=42 TRANSFER_AMOUNT=21 source $TEST_FOLDER/shared/deploy_main_account_and_token.sh -source $TEST_FOLDER/shared/mint_to_private.sh $MINT_AMOUNT +source $TEST_FOLDER/shared/mint_to_private.sh $MINT_AMOUNT main source $TEST_FOLDER/shared/create_funded_account.sh operator aztec-wallet create-secret -a auth_nonce diff --git a/yarn-project/cli-wallet/test/flows/private_transfer.sh b/yarn-project/cli-wallet/test/flows/private_transfer.sh index 79036e1a12c4..01fa122cd8a0 100755 --- a/yarn-project/cli-wallet/test/flows/private_transfer.sh +++ b/yarn-project/cli-wallet/test/flows/private_transfer.sh @@ -8,7 +8,7 @@ MINT_AMOUNT=42 TRANSFER_AMOUNT=21 source $TEST_FOLDER/shared/deploy_main_account_and_token.sh -source $TEST_FOLDER/shared/mint_to_private.sh $MINT_AMOUNT +source $TEST_FOLDER/shared/mint_to_private.sh $MINT_AMOUNT main aztec-wallet create-account -a recipient --register-only diff --git a/yarn-project/cli-wallet/test/flows/profile.sh b/yarn-project/cli-wallet/test/flows/profile.sh index 2f7801f981ea..9c43bfe2812f 100755 --- a/yarn-project/cli-wallet/test/flows/profile.sh +++ b/yarn-project/cli-wallet/test/flows/profile.sh @@ -11,7 +11,7 @@ warn /////////////////////////////////////////////////////////////////////////// echo source $TEST_FOLDER/shared/deploy_main_account_and_token.sh -source $TEST_FOLDER/shared/mint_to_private.sh 100 +source $TEST_FOLDER/shared/mint_to_private.sh 100 main source $TEST_FOLDER/shared/create_funded_account.sh operator # Create an authwit for the operator to transfer tokens from the main account to operator's own account. diff --git a/yarn-project/cli-wallet/test/flows/public_authwit_transfer.sh b/yarn-project/cli-wallet/test/flows/public_authwit_transfer.sh index 86c7b47cde71..8712dce51307 100755 --- a/yarn-project/cli-wallet/test/flows/public_authwit_transfer.sh +++ b/yarn-project/cli-wallet/test/flows/public_authwit_transfer.sh @@ -8,7 +8,7 @@ MINT_AMOUNT=42 TRANSFER_AMOUNT=21 source $TEST_FOLDER/shared/deploy_main_account_and_token.sh -source $TEST_FOLDER/shared/mint_to_public.sh $MINT_AMOUNT +source $TEST_FOLDER/shared/mint_to_public.sh $MINT_AMOUNT main source $TEST_FOLDER/shared/create_funded_account.sh operator aztec-wallet create-secret -a auth_nonce diff --git a/yarn-project/cli-wallet/test/flows/shared/create_funded_account.sh b/yarn-project/cli-wallet/test/flows/shared/create_funded_account.sh index 2660b6d1b92c..973042d30b6a 100644 --- a/yarn-project/cli-wallet/test/flows/shared/create_funded_account.sh +++ b/yarn-project/cli-wallet/test/flows/shared/create_funded_account.sh @@ -1,16 +1,12 @@ ALIAS=$1 -section "Creating a funded account. Alias: $ALIAS" +section "Creating a funded account (alias: $ALIAS)" aztec-wallet create-account -a $ALIAS --register-only aztec-wallet bridge-fee-juice 100000000000000000 $ALIAS --mint --no-wait -# These two txs produce two blocks, allowing the claim to be used in the next block. -aztec-wallet import-test-accounts -TMP_ALIAS="tmp-$ALIAS" -aztec-wallet deploy counter_contract@Counter --init initialize --args 0 accounts:test0 -f test0 -a $TMP_ALIAS -aztec-wallet send increment -ca $TMP_ALIAS --args accounts:test0 accounts:test0 -f test0 +# The following produces two blocks, allowing the claim to be used in the next block. +source $TEST_FOLDER/shared/deploy_token.sh tmp-token-$ALIAS $ALIAS # Deploying the account, paying the fee via bridging fee juice from L1 using the claim created above. -# aztec-wallet deploy-account -f $ALIAS --payment method=fee_juice,claim aztec-wallet deploy-account -f $ALIAS --payment method=fee_juice,claim diff --git a/yarn-project/cli-wallet/test/flows/shared/deploy_main_account_and_token.sh b/yarn-project/cli-wallet/test/flows/shared/deploy_main_account_and_token.sh index 01b7bb6a42d4..b8164d438cd6 100644 --- a/yarn-project/cli-wallet/test/flows/shared/deploy_main_account_and_token.sh +++ b/yarn-project/cli-wallet/test/flows/shared/deploy_main_account_and_token.sh @@ -1,13 +1,14 @@ -section "Deploying token contract and creating a funded main account" +TOKEN_ALIAS=token +ACCOUNT_ALIAS=main -aztec-wallet create-account -a main --register-only -aztec-wallet bridge-fee-juice 100000000000000000 main --mint --no-wait +section "Deploying token contract (alias: $TOKEN_ALIAS) and creating a funded account (alias: $ACCOUNT_ALIAS)" -# Deploy token contract and set the main account as a minter using the pre-funded test account. -# These two txs produce two blocks, allowing the claim to be used in the next block. -aztec-wallet import-test-accounts -aztec-wallet deploy token_contract@Token --args accounts:test0 Test TST 18 -f test0 -a token -aztec-wallet send set_minter -ca token --args accounts:main true -f test0 +aztec-wallet create-account -a $ACCOUNT_ALIAS --register-only +aztec-wallet bridge-fee-juice 100000000000000000 $ACCOUNT_ALIAS --mint --no-wait + +# Deploy token contract and set the main account as a minter. +# The following produces two blocks, allowing the claim to be used in the next block. +source $TEST_FOLDER/shared/deploy_token.sh $TOKEN_ALIAS $ACCOUNT_ALIAS # Deploying the account, paying the fee via bridging fee juice from L1 using the claim created above. -aztec-wallet deploy-account -f main --payment method=fee_juice,claim +aztec-wallet deploy-account -f $ACCOUNT_ALIAS --payment method=fee_juice,claim diff --git a/yarn-project/cli-wallet/test/flows/shared/deploy_sponsored_fpc_and_token.sh b/yarn-project/cli-wallet/test/flows/shared/deploy_sponsored_fpc_and_token.sh new file mode 100644 index 000000000000..0c51b2e22dc7 --- /dev/null +++ b/yarn-project/cli-wallet/test/flows/shared/deploy_sponsored_fpc_and_token.sh @@ -0,0 +1,25 @@ +TOKEN_ALIAS=token +FPC_ALIAS=sponsoredFPC + +section "Deploying token contract (alias: $TOKEN_ALIAS) and creating a sponsored fpc (alias: $FPC_ALIAS)" + +aztec-wallet import-test-accounts +aztec-wallet deploy sponsored_fpc_contract@SponsoredFPC -f test0 -a $FPC_ALIAS --no-init + +CLAIM=$(aztec-wallet bridge-fee-juice 100000000000000000 contracts:$FPC_ALIAS --mint --no-wait --json) + +retrieve () { + echo "$CLAIM" | grep "\"$1\"" | awk -F ': ' '{print $2}' | tr -d '",' +} + +claimAmount=$(retrieve claimAmount) +claimSecret=$(retrieve claimSecret) +messageLeafIndex=$(retrieve messageLeafIndex) + +# The following produces two blocks, allowing the claim to be used in the next block. +source $TEST_FOLDER/shared/deploy_token.sh $TOKEN_ALIAS test1 + +# Claim the fee juice by calling the fee juice contract directly (address = 5). +feeJuice=0x0000000000000000000000000000000000000000000000000000000000000005 +# Using a pre-funded test account because SponsoredFPC is not an account contract and can't be used to send a tx. +aztec-wallet send claim -ca $feeJuice -c fee_juice_contract@FeeJuice --args contracts:$FPC_ALIAS $claimAmount $claimSecret $messageLeafIndex -f test0 diff --git a/yarn-project/cli-wallet/test/flows/shared/deploy_token.sh b/yarn-project/cli-wallet/test/flows/shared/deploy_token.sh new file mode 100644 index 000000000000..02a83462ad88 --- /dev/null +++ b/yarn-project/cli-wallet/test/flows/shared/deploy_token.sh @@ -0,0 +1,8 @@ +TOKEN_ALIAS=$1 +MINTER=$2 + +section "Deploying token contract (alias: $TOKEN_ALIAS) and setting '$MINTER' as a minter" + +aztec-wallet import-test-accounts +aztec-wallet deploy token_contract@Token --args accounts:test0 Test TST 18 -f test0 -a $TOKEN_ALIAS +aztec-wallet send set_minter -ca $TOKEN_ALIAS --args accounts:$MINTER true -f test0 diff --git a/yarn-project/cli-wallet/test/flows/shared/mint_to_private.sh b/yarn-project/cli-wallet/test/flows/shared/mint_to_private.sh index 2dedc6e015ec..e40abe364d5c 100644 --- a/yarn-project/cli-wallet/test/flows/shared/mint_to_private.sh +++ b/yarn-project/cli-wallet/test/flows/shared/mint_to_private.sh @@ -1,11 +1,6 @@ -section "Minting tokens privately" +MINT_AMOUNT=$1 +MINTER=$2 -aztec-wallet send mint_to_private -ca token --args accounts:main accounts:main $1 -f main +section "Minting $MINT_AMOUNT tokens to $MINTER privately" -RESULT_MAIN=$(aztec-wallet simulate balance_of_private -ca token --args accounts:main -f main | grep "Simulation result:" | awk '{print $3}') - -if [ "${1}n" != "$RESULT_MAIN" ]; then - echo - err "Couldn't mint tokens" - exit 1 -fi +aztec-wallet send mint_to_private -ca token --args accounts:$MINTER accounts:$MINTER $MINT_AMOUNT -f $MINTER diff --git a/yarn-project/cli-wallet/test/flows/shared/mint_to_public.sh b/yarn-project/cli-wallet/test/flows/shared/mint_to_public.sh index 7a297cf93ccb..2826f2eee104 100644 --- a/yarn-project/cli-wallet/test/flows/shared/mint_to_public.sh +++ b/yarn-project/cli-wallet/test/flows/shared/mint_to_public.sh @@ -1,11 +1,6 @@ -section "Minting tokens publicly" +MINT_AMOUNT=$1 +MINTER=$2 -aztec-wallet send mint_to_public -ca token --args accounts:main $1 -f main +section "Minting $MINT_AMOUNT tokens to $MINTER publicly" -RESULT_MAIN=$(aztec-wallet simulate balance_of_public -ca token --args accounts:main -f main | grep "Simulation result:" | awk '{print $3}') - -if [ "${1}n" != "$RESULT_MAIN" ]; then - echo - err "Couldn't mint tokens" - exit 1 -fi +aztec-wallet send mint_to_public -ca token --args accounts:$MINTER $MINT_AMOUNT -f $MINTER diff --git a/yarn-project/cli-wallet/test/flows/shield_and_transfer.sh b/yarn-project/cli-wallet/test/flows/shield_and_transfer.sh index 6332bf1f9413..1b23d8190d1c 100755 --- a/yarn-project/cli-wallet/test/flows/shield_and_transfer.sh +++ b/yarn-project/cli-wallet/test/flows/shield_and_transfer.sh @@ -8,7 +8,7 @@ MINT_AMOUNT=42 TRANSFER_AMOUNT=21 source $TEST_FOLDER/shared/deploy_main_account_and_token.sh -source $TEST_FOLDER/shared/mint_to_private.sh $MINT_AMOUNT +source $TEST_FOLDER/shared/mint_to_private.sh $MINT_AMOUNT main aztec-wallet create-account -a recipient --register-only diff --git a/yarn-project/cli-wallet/test/flows/sponsored_create_account_and_mint.sh b/yarn-project/cli-wallet/test/flows/sponsored_create_account_and_mint.sh new file mode 100755 index 000000000000..af9674ed4f58 --- /dev/null +++ b/yarn-project/cli-wallet/test/flows/sponsored_create_account_and_mint.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -e +source ../utils/setup.sh + +test_title "Create new account and mint privately. Fees paid by a sponsor." + +MINT_AMOUNT=42 + +source $TEST_FOLDER/shared/deploy_sponsored_fpc_and_token.sh + +PAYMENT_METHOD="--payment method=fpc-sponsored,fpc=contracts:sponsoredFPC" + +aztec-wallet create-account -a user $PAYMENT_METHOD + +aztec-wallet send set_minter -ca token --args accounts:user true -f test0 $PAYMENT_METHOD + +aztec-wallet send mint_to_private -ca token --args accounts:user accounts:user $MINT_AMOUNT -f user $PAYMENT_METHOD + +RESULT=$(aztec-wallet simulate balance_of_private -ca token --args accounts:user -f user | grep "Simulation result:" | awk '{print $3}') + +assert_eq ${RESULT} "${MINT_AMOUNT}n"