@@ -16,10 +16,8 @@ import TrackBlockEventsAsync from "./Helper/AztecEventTracker";
1616import { createRefundCallData , createLockCallData , createRedeemCallData , createCommitCallData } from "./Helper/AztecTransactionBuilder" ;
1717import { TransactionFailedException } from "../../Blockchain.Abstraction/Exceptions/TransactionFailedException" ;
1818import { Tx , TxHash } from "@aztec/aztec.js/tx" ;
19- import { createAztecNodeClient } from '@aztec/aztec.js/node' ;
2019import { mapAztecStatusToInternal } from "./Helper/AztecTransactionStatusMapper" ;
2120import { AztecPublishTransactionRequest } from "../Models/AztecPublishTransactionRequest" ;
22- import { TreasuryClient } from "../../Blockchain.Abstraction/Infrastructure/TreasuryClient/treasuryClient" ;
2321import { AztecSignTransactionRequestModel } from "./Models/AztecSignTransactionModel" ;
2422import { buildLockKey as buildLockKey , buildCurrentNonceKey , buildNextNonceKey } from "../../Blockchain.Abstraction/Infrastructure/RedisHelper/RedisHelper" ;
2523import { NextNonceRequest } from "../../Blockchain.Abstraction/Models/NonceModels/NextNonceRequest" ;
@@ -29,12 +27,34 @@ import Redis from "ioredis";
2927import Redlock from "redlock" ;
3028import { TimeSpan } from "../../Blockchain.Abstraction/Infrastructure/RedisHelper/TimeSpanConverter" ;
3129import { TransactionNotComfirmedException } from "../../Blockchain.Abstraction/Exceptions/TransactionNotComfirmedException" ;
30+ import { TrainContract } from "./Helper/Train" ;
31+ import { PrivateKeyService } from '../KeyVault/vault.service' ;
32+ import { ContractFunctionInteraction , getContractInstanceFromInstantiationParams , toSendOptions } from '@aztec/aztec.js/contracts' ;
33+ import { SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee' ;
34+ import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC' ;
35+ import { TestWallet } from '@aztec/test-wallet/server' ;
36+ import { createStore } from '@aztec/kv-store/lmdb' ;
37+ import { AztecNode , createAztecNodeClient } from '@aztec/aztec.js/node' ;
38+ import { getPXEConfig } from '@aztec/pxe/server' ;
39+ import { Fr } from '@aztec/aztec.js/fields' ;
40+ import { deriveSigningKey } from '@aztec/stdlib/keys' ;
41+ import { AztecAddress } from '@aztec/aztec.js/addresses' ;
42+ import { TokenContract } from '@aztec/noir-contracts.js/Token' ;
43+ import { AuthWitness } from '@aztec/stdlib/auth-witness' ;
44+ import { ContractFunctionInteractionCallIntent } from '@aztec/aztec.js/authorization' ;
45+ import { ContractArtifact , FunctionAbi , getAllFunctionAbis } from '@aztec/aztec.js/abi' ;
46+ import { SchnorrAccountContract } from '@aztec/accounts/schnorr' ;
47+ import { getAccountContractAddress } from '@aztec/aztec.js/account' ;
48+ import { AztecFunctionInteractionModel } from "./Models/AztecFunctionInteractionModel" ;
49+ import { AztecConfigService } from "../KeyVault/aztec.config" ;
3250
3351@injectable ( )
3452export class AztecBlockchainActivities implements IAztecBlockchainActivities {
3553 constructor (
3654 @inject ( "Redis" ) private redis : Redis ,
3755 @inject ( "Redlock" ) private lockFactory : Redlock ,
56+ @inject ( "PrivateKeyService" ) private privateKeyService : PrivateKeyService ,
57+ @inject ( "AztecConfigService" ) private aztecConfigService : AztecConfigService ,
3858 ) { }
3959
4060 public async BuildTransaction ( request : TransactionBuilderRequest ) : Promise < PrepareTransactionResponse > {
@@ -114,12 +134,137 @@ export class AztecBlockchainActivities implements IAztecBlockchainActivities {
114134 }
115135
116136 public async signTransaction ( request : AztecSignTransactionRequestModel ) : Promise < string > {
137+ try {
138+ const privateKey = await this . privateKeyService . getAsync ( request . solverAddress ) ;
139+ const privateSalt = await this . privateKeyService . getAsync ( request . solverAddress , "private_salt" ) ;
140+ const provider : AztecNode = createAztecNodeClient ( request . nodeUrl ) ;
141+ const l1Contracts = await provider . getL1ContractAddresses ( ) ;
142+
143+ const fullConfig = { ...getPXEConfig ( ) , l1Contracts, proverEnabled : true } ;
144+
145+ const accountContract = new SchnorrAccountContract ( deriveSigningKey ( Fr . fromString ( privateKey ) ) ) ;
146+ const solverAddress = ( await getAccountContractAddress ( accountContract , Fr . fromString ( privateKey ) , Fr . fromString ( privateSalt ) ) ) . toString ( ) ;
147+
148+ const store = await createStore ( request . solverAddress , {
149+ dataDirectory : this . aztecConfigService . storePath ,
150+ dataStoreMapSizeKb : 1e6 ,
151+ } ) ;
152+
153+ const pxe = await TestWallet . create ( provider , fullConfig , { store } ) ;
154+
155+ const sponsoredFPCInstance = await getContractInstanceFromInstantiationParams (
156+ SponsoredFPCContract . artifact ,
157+ { salt : new Fr ( 0 ) } ,
158+ ) ;
159+
160+ await pxe . registerContract (
161+ sponsoredFPCInstance ,
162+ SponsoredFPCContract . artifact ,
163+ ) ;
164+
165+ await pxe . createSchnorrAccount (
166+ Fr . fromString ( privateKey ) ,
167+ Fr . fromString ( privateSalt ) ,
168+ deriveSigningKey ( Fr . fromString ( privateKey ) ) ,
169+ ) ;
170+
171+ const contractInstanceWithAddress = await provider . getContract ( AztecAddress . fromString ( request . contractAddress ) ) ;
172+ await pxe . registerContract ( contractInstanceWithAddress , TrainContract . artifact ) ;
173+
174+ const tokenInstance = await provider . getContract ( AztecAddress . fromString ( request . tokenContract ) ) ;
175+ await pxe . registerContract ( tokenInstance , TokenContract . artifact )
176+
177+ const contractFunctionInteraction : AztecFunctionInteractionModel = JSON . parse ( request . unsignedTxn ) ;
178+ let authWitnesses : AuthWitness [ ] = [ ] ;
179+
180+ if ( contractFunctionInteraction . authwiths ) {
181+ for ( const authWith of contractFunctionInteraction . authwiths ) {
182+ const requestContractClass = await provider . getContract ( AztecAddress . fromString ( authWith . interactionAddress ) ) ;
183+ const contractClassMetadata = await pxe . getContractClassMetadata ( requestContractClass . currentContractClassId , true ) ;
184+
185+ if ( ! contractClassMetadata . artifact ) {
186+ throw new Error ( `Artifact not registered` ) ;
187+ }
188+
189+ const functionAbi = getFunctionAbi ( contractClassMetadata . artifact , authWith . functionName ) ;
190+
191+ if ( ! functionAbi ) {
192+ throw new Error ( "Unable to get function ABI" ) ;
193+ }
194+
195+ authWith . args . unshift ( solverAddress ) ;
117196
118- const treasuryClient = new TreasuryClient ( request . signerAgentUrl ) ;
197+ const functionInteraction = new ContractFunctionInteraction (
198+ pxe ,
199+ AztecAddress . fromString ( authWith . interactionAddress ) ,
200+ functionAbi ,
201+ [ ...authWith . args ] ,
202+ ) ;
119203
120- const response = await treasuryClient . signTransaction ( request . networkType , request . signRequest ) ;
204+ const intent : ContractFunctionInteractionCallIntent = {
205+ caller : AztecAddress . fromString ( authWith . callerAddress ) ,
206+ action : functionInteraction ,
207+ } ;
121208
122- return response . signedTxn ;
209+ const witness = await pxe . createAuthWit (
210+ AztecAddress . fromString ( solverAddress ) ,
211+ intent ,
212+ ) ;
213+
214+ authWitnesses . push ( witness ) ;
215+ }
216+ }
217+
218+ const requestcontractClass = await provider . getContract ( AztecAddress . fromString ( contractFunctionInteraction . interactionAddress ) )
219+ const contractClassMetadata = await pxe . getContractClassMetadata ( requestcontractClass . currentContractClassId , true )
220+
221+ if ( ! contractClassMetadata . artifact ) {
222+ throw new Error ( `Artifact not registered` ) ;
223+ }
224+
225+ const functionAbi = getFunctionAbi ( contractClassMetadata . artifact , contractFunctionInteraction . functionName ) ;
226+
227+ const functionInteraction = new ContractFunctionInteraction (
228+ pxe ,
229+ AztecAddress . fromString ( contractFunctionInteraction . interactionAddress ) ,
230+ functionAbi ,
231+ [
232+ ...contractFunctionInteraction . args
233+ ] ,
234+ [ ...authWitnesses ]
235+ ) ;
236+
237+ const executionPayload = await functionInteraction . request ( {
238+ authWitnesses : [ ...authWitnesses ] ,
239+ fee : { paymentMethod : new SponsoredFeePaymentMethod ( sponsoredFPCInstance . address ) } ,
240+ } ) ;
241+
242+ var sendOptions = await toSendOptions (
243+ {
244+ from : AztecAddress . fromString ( request . solverAddress ) ,
245+ authWitnesses : [ ...authWitnesses ] ,
246+ fee : { paymentMethod : new SponsoredFeePaymentMethod ( sponsoredFPCInstance . address ) } ,
247+ } ,
248+ ) ;
249+
250+ const provenTx = await pxe . proveTx ( executionPayload , sendOptions ) ;
251+
252+ const tx = new Tx (
253+ provenTx . getTxHash ( ) ,
254+ provenTx . data ,
255+ provenTx . clientIvcProof ,
256+ provenTx . contractClassLogFields ,
257+ provenTx . publicFunctionCalldata ,
258+ ) ;
259+
260+ const signedTxHex = tx . toBuffer ( ) . toString ( "hex" ) ;
261+ const signedTxn = JSON . stringify ( { signedTx : signedTxHex } ) ;
262+
263+ return signedTxn ;
264+ }
265+ catch ( error ) {
266+ throw new Error ( `Error while signing transaction: ${ error . message } ` ) ;
267+ }
123268 }
124269
125270 public async publishTransaction ( request : AztecPublishTransactionRequest ) : Promise < string > {
@@ -208,3 +353,12 @@ export class AztecBlockchainActivities implements IAztecBlockchainActivities {
208353 throw new Error ( "Method not implemented." ) ;
209354 }
210355}
356+
357+ function getFunctionAbi (
358+ artifact : ContractArtifact ,
359+ fnName : string ,
360+ ) : FunctionAbi | undefined {
361+ const fn = getAllFunctionAbis ( artifact ) . find ( ( { name } ) => name === fnName ) ;
362+ if ( ! fn ) { }
363+ return fn ;
364+ }
0 commit comments