Skip to content

Commit a204cbd

Browse files
authored
Merge pull request #144 from TrainProtocol/dev-moveAztecTreasury
Dev move aztec treasury
2 parents 2371966 + e27a95d commit a204cbd

File tree

16 files changed

+4382
-4395
lines changed

16 files changed

+4382
-4395
lines changed

js/package-lock.json

Lines changed: 298 additions & 595 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
"@aztec/bb-prover": "3.0.0-devnet.2",
1717
"@aztec/noir-contracts.js": "3.0.0-devnet.2",
1818
"@aztec/pxe": "3.0.0-devnet.2",
19-
"@aztec/test-wallet": "^3.0.0-devnet.2",
19+
"@aztec/test-wallet": "3.0.0-devnet.2",
2020
"@temporalio/worker": "^1.12.1",
21+
"@nestjs/common": "11.1.2",
22+
"@nestjs/config": "^4.0.2",
2123
"axios": "^1.11.0",
2224
"dotenv": "^16.4.7",
2325
"ethers": "^5.8.0",

js/src/Blockchain/Blockchain.Abstraction/Infrastructure/AddCoreServices.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import Redis from 'ioredis';
33
import Redlock from 'redlock';
44
import { container } from 'tsyringe';
55
import { ConvertToRedisUrl } from './RedisHelper/RedisFactory';
6+
import { PrivateKeyService } from '../../Blockchain.Aztec/KeyVault/vault.service';
7+
import { PrivateKeyConfigService } from '../../Blockchain.Aztec/KeyVault/vault.config';
8+
import { AztecConfigService } from '../../Blockchain.Aztec/KeyVault/aztec.config';
69

710
export async function AddCoreServices(): Promise<void> {
811

@@ -13,7 +16,18 @@ export async function AddCoreServices(): Promise<void> {
1316
retryDelay: 200,
1417
retryJitter: 100,
1518
});
19+
const configService = {
20+
get: (key: string) => process.env[key]
21+
};
22+
23+
const privateKeyConfigService = new PrivateKeyConfigService(configService as any);
24+
const privateKeyService = new PrivateKeyService();
25+
26+
privateKeyService.init(privateKeyConfigService);
27+
const aztecConfigService = new AztecConfigService(configService as any);
1628

1729
container.register<Redlock>("Redlock", { useValue: redlock });
1830
container.register<Redis>("Redis", { useValue: redis });
31+
container.register<PrivateKeyService>("PrivateKeyService", { useValue: privateKeyService });
32+
container.register<AztecConfigService>("AztecConfigService", { useValue: aztecConfigService });
1933
}

js/src/Blockchain/Blockchain.Aztec/Activities/ABIs/train.json

Lines changed: 3582 additions & 3770 deletions
Large diffs are not rendered by default.

js/src/Blockchain/Blockchain.Aztec/Activities/AztecBlockchainActivities.ts

Lines changed: 159 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ import TrackBlockEventsAsync from "./Helper/AztecEventTracker";
1616
import { createRefundCallData, createLockCallData, createRedeemCallData, createCommitCallData } from "./Helper/AztecTransactionBuilder";
1717
import { TransactionFailedException } from "../../Blockchain.Abstraction/Exceptions/TransactionFailedException";
1818
import { Tx, TxHash } from "@aztec/aztec.js/tx";
19-
import { createAztecNodeClient } from '@aztec/aztec.js/node';
2019
import { mapAztecStatusToInternal } from "./Helper/AztecTransactionStatusMapper";
2120
import { AztecPublishTransactionRequest } from "../Models/AztecPublishTransactionRequest";
22-
import { TreasuryClient } from "../../Blockchain.Abstraction/Infrastructure/TreasuryClient/treasuryClient";
2321
import { AztecSignTransactionRequestModel } from "./Models/AztecSignTransactionModel";
2422
import { buildLockKey as buildLockKey, buildCurrentNonceKey, buildNextNonceKey } from "../../Blockchain.Abstraction/Infrastructure/RedisHelper/RedisHelper";
2523
import { NextNonceRequest } from "../../Blockchain.Abstraction/Models/NonceModels/NextNonceRequest";
@@ -29,12 +27,34 @@ import Redis from "ioredis";
2927
import Redlock from "redlock";
3028
import { TimeSpan } from "../../Blockchain.Abstraction/Infrastructure/RedisHelper/TimeSpanConverter";
3129
import { 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()
3452
export 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+
}

js/src/Blockchain/Blockchain.Aztec/Activities/Helper/AztecTransactionBuilder.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Fr } from '@aztec/foundation/fields';
99
import { PrepareTransactionResponse } from "../../../Blockchain.Abstraction/Models/TransactionBuilderModels/TransferBuilderResponse";
1010
import crypto from 'crypto';
1111
import { TransferPrepareRequest } from "../../../Blockchain.Abstraction/Models/TransactionBuilderModels/TransferPrepareRequest";
12+
import { AztecFunctionInteractionModel } from "../Models/AztecFunctionInteractionModel";
1213

1314
export async function createRefundCallData(network: DetailedNetworkDto, args: string): Promise<PrepareTransactionResponse> {
1415

@@ -23,7 +24,7 @@ export async function createRefundCallData(network: DetailedNetworkDto, args: st
2324
? network.htlcNativeContractAddress
2425
: network.htlcTokenContractAddress;
2526

26-
let functionInteraction: FunctionInteraction = {
27+
let functionInteraction: AztecFunctionInteractionModel = {
2728
interactionAddress: htlcContractAddress,
2829
functionName: "refund_private",
2930
args: [refundRequest.commitId],
@@ -54,7 +55,7 @@ export async function createCommitCallData(network: DetailedNetworkDto, args: st
5455

5556
const randomness = BigInt('0x' + crypto.randomBytes(31).toString('hex')).toString()
5657

57-
let functionInteraction: FunctionInteraction = {
58+
let functionInteraction: AztecFunctionInteractionModel = {
5859
interactionAddress: htlcContractAddress,
5960
functionName: "commit_private_user",
6061
args: [
@@ -107,7 +108,7 @@ export async function createRedeemCallData(network: DetailedNetworkDto, args: st
107108
const [secretHigh, secretLow] = hexToU128Limbs(toHex((BigInt(redeemRequest.secret))));
108109
const [ownershipKeyHigh, ownershipKeyLow] = hexToU128Limbs(toHex(BigInt(redeemRequest.secret)));
109110

110-
let functionInteraction: FunctionInteraction = {
111+
let functionInteraction: AztecFunctionInteractionModel = {
111112
interactionAddress: htlcContractAddress,
112113
functionName: "redeem_private",
113114
args: [
@@ -147,7 +148,7 @@ export async function createLockCallData(network: DetailedNetworkDto, args: stri
147148
const hashlock = hexToU128Limbs(lockRequest.hashlock);
148149
const ownershipHash = hexToU128Limbs(normalizeHex(lockRequest.receiver));
149150

150-
let functionInteraction: FunctionInteraction = {
151+
let functionInteraction: AztecFunctionInteractionModel = {
151152
interactionAddress: htlcContractAddress,
152153
functionName: "lock_private_solver",
153154
args: [
@@ -195,7 +196,7 @@ export async function createTransferCallData(network: DetailedNetworkDto, args:
195196
throw new Error(`Token not found for network ${network.name} and asset ${transferRequest.asset}`)
196197
};
197198

198-
let functionInteraction: FunctionInteraction = {
199+
let functionInteraction: AztecFunctionInteractionModel = {
199200
interactionAddress: token.contract,
200201
functionName: "transfer",
201202
args: [
@@ -214,14 +215,6 @@ export async function createTransferCallData(network: DetailedNetworkDto, args:
214215
};
215216
}
216217

217-
interface FunctionInteraction {
218-
interactionAddress: string,
219-
functionName: string,
220-
args: any[],
221-
callerAddress?: string,
222-
authwiths?: FunctionInteraction[],
223-
}
224-
225218
export const hexToUint256HexStrings = (hex: string): string[] => {
226219
let h = hex.startsWith('0x') ? hex.slice(2) : hex;
227220
if (h.length % 2) h = '0' + h;

0 commit comments

Comments
 (0)