-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathinit-comp-def-final.ts
More file actions
143 lines (120 loc) Β· 5.49 KB
/
init-comp-def-final.ts
File metadata and controls
143 lines (120 loc) Β· 5.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import * as fs from 'fs';
import * as os from 'os';
import * as anchor from '@coral-xyz/anchor';
import BN from 'bn.js';
import {
getCompDefAccOffset,
getMXEAccAddress,
getArciumAccountBaseSeed,
getArciumProgramId,
getLookupTableAddress,
getArciumProgram,
} from '@arcium-hq/client';
import { PublicKey, AddressLookupTableProgram } from '@solana/web3.js';
// The ID used in the program for payment stats
const CIRCUIT_ID = 'payment_v3';
async function initCompDefFinal() {
console.log('π Starting FINAL Computation Definition initialization for payment_stats...');
// Setup provider
const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);
// Get program
const program = anchor.workspace.BleRevshare as anchor.Program;
console.log('π Using program ID:', program.programId.toString());
// Get owner keypair
const walletPath = process.env.ANCHOR_WALLET || `${os.homedir()}/.config/solana/id.json`;
console.log('π Using wallet:', walletPath);
const owner = anchor.web3.Keypair.fromSecretKey(
new Uint8Array(JSON.parse(fs.readFileSync(walletPath, 'utf8')))
);
console.log('π€ Owner public key:', owner.publicKey.toString());
// Get computation definition PDA
const baseSeedCompDefAcc = getArciumAccountBaseSeed("ComputationDefinitionAccount");
const offsetUint8Array = getCompDefAccOffset(CIRCUIT_ID);
const offsetBuffer = Buffer.from(offsetUint8Array);
const [compDefPDA] = PublicKey.findProgramAddressSync(
[baseSeedCompDefAcc, program.programId.toBuffer(), offsetBuffer],
getArciumProgramId()
);
console.log('π― Computation definition PDA:', compDefPDA.toString());
console.log('π’ Offset:', Buffer.from(offsetUint8Array).readUInt32LE(0));
const mxeAddress = getMXEAccAddress(program.programId);
try {
// STEP 1: Initialize the computation definition account
console.log('\n=== STEP 1: Initializing computation definition account ===');
// Fetch lutOffsetSlot from MXE account for LUT derivation
let lutOffsetSlot = new BN(0);
try {
const arciumProg = getArciumProgram(provider);
const mxeData = await arciumProg.account['mxeAccount'].fetch(mxeAddress);
lutOffsetSlot = (mxeData as any).lutOffsetSlot;
console.log('π’ LUT offset slot:', lutOffsetSlot.toString());
} catch (e) {
console.warn('β οΈ Could not fetch lutOffsetSlot, using 0:', e);
}
const addressLookupTable = getLookupTableAddress(program.programId, lutOffsetSlot);
console.log('ποΈ Address Lookup Table:', addressLookupTable.toString());
const existingAccount = await provider.connection.getAccountInfo(compDefPDA);
if (existingAccount) {
console.log('β οΈ Comp def account exists β closing it for re-initialization...');
// Drain lamports to payer by sending a transfer (relies on payer being the owner)
// Anchor init will fail if account exists, so we need to close it first.
// Use Arcium's close if available, otherwise inform the user.
console.log('βΉοΈ Close the account manually at:', compDefPDA.toString());
console.log('βΉοΈ Or run: solana account', compDefPDA.toString(), '--output json');
console.log('βΉοΈ Then re-run this script.');
console.log('\nAttempting init anyway (works if Arcium program supports re-init)...');
}
try {
const tx = await program.methods
.initPaymentStatsCompDef()
.accounts({
compDefAccount: compDefPDA,
payer: owner.publicKey,
mxeAccount: mxeAddress,
addressLookupTable,
lutProgram: AddressLookupTableProgram.programId,
})
.signers([owner])
.transaction();
// Simulate first to catch on-chain errors with logs
const { blockhash, lastValidBlockHeight } = await provider.connection.getLatestBlockhash('confirmed');
tx.recentBlockhash = blockhash;
tx.feePayer = owner.publicKey;
tx.sign(owner);
const sim = await provider.connection.simulateTransaction(tx);
console.log('π Simulation logs:', sim.value.logs);
if (sim.value.err) {
throw new Error(`Simulation failed: ${JSON.stringify(sim.value.err)}\nLogs:\n${sim.value.logs?.join('\n')}`);
}
const rawTx = tx.serialize();
const sig = await provider.connection.sendRawTransaction(rawTx, { skipPreflight: true });
console.log('π€ Sent tx:', sig);
await provider.connection.confirmTransaction({ signature: sig, blockhash, lastValidBlockHeight }, 'confirmed');
console.log('β
Initialization transaction:', sig);
await new Promise(resolve => setTimeout(resolve, 2000));
} catch (err: any) {
if (err.message?.includes('already in use') || err.message?.includes('already initialized')) {
console.error('β Comp def account already in use.');
} else {
console.error('β Failed:', err.message);
}
throw err;
}
console.log('\n=== STEP 2: Computation Definition Setup ===');
console.log('π Circuit Source: OffChain (IPFS)');
console.log('\n=== STEP 3: Finalization skipped (OffChain circuit) ===');
console.log('\nπ SUCCESS! Computation definition is ready!');
} catch (error) {
console.error('β Error during computation definition setup:', error);
if (error.logs) {
console.error('π Transaction logs:');
error.logs.forEach((log: string) => console.error(' ', log));
}
process.exit(1);
}
}
initCompDefFinal().catch((error) => {
console.error('π₯ Fatal error:', error);
process.exit(1);
});