UNPKG

o1js

Version:

TypeScript framework for zk-SNARKs and zkApps

132 lines (114 loc) 3.69 kB
import { Bool, Experimental, Field, PrivateKey, PublicKey, UInt32 } from 'o1js'; const V2 = Experimental.V2; type TestState = { x: typeof Field; address: typeof PublicKey; }; const TestState: Experimental.V2.StateDefinition<TestState> = V2.State({ x: Field, address: PublicKey, }); const TestProgram = V2.MinaProgram({ name: 'TestProgram', State: TestState, Event: V2.GenericData, Action: V2.GenericData, methods: { init: { privateInputs: [Field], async method( env: Experimental.V2.MinaProgramEnv<TestState>, value: Field ): Promise<Experimental.V2.MinaProgramMethodReturn<TestState>> { return { incrementNonce: new Bool(true), preconditions: { account: { isProven: new Bool(false), nonce: new UInt32(0), }, }, setState: { x: V2.Update.from(value, Field(0)) as never, address: V2.Update.from(env.accountId.publicKey, PublicKey.empty()) as never, }, pushActions: [ [Field(1), Field(2)], [Field(3), Field(4)], ], }; }, }, }, }); const compiledTestProgram = await TestProgram.compile(); const feePayerKey = PrivateKey.random(); const feePayerAddress = feePayerKey.toPublicKey(); const feePayer = V2.Account.empty(new V2.AccountId(feePayerAddress, V2.TokenId.MINA)); feePayer.nonce = new UInt32(4); feePayer.balance = V2.MinaAmount.fromMINA(1000); const appKey = PrivateKey.random(); const app = V2.Account.empty(new V2.AccountId(appKey.toPublicKey(), V2.TokenId.MINA)); console.log( `feePayer = ${JSON.stringify(feePayerAddress)}, app = ${JSON.stringify(app.accountId.publicKey)}` ); const testLedger = new V2.LocalLedger([feePayer]); const authEnv: Experimental.V2.ZkappCommandAuthorizationEnvironment = { networkId: 'testnet', async getPrivateKey(pk: PublicKey): Promise<PrivateKey> { if (pk === feePayerAddress) return feePayerKey; if (pk === app.accountId.publicKey) return appKey; throw new Error(); }, }; const testTransaction = await V2.createZkappCommand( testLedger, V2.LocalChain.initial(), authEnv, { feePayer: feePayerAddress, fee: V2.MinaAmount.fromMINA(1), }, async (ctx) => { ctx.add( V2.AccountUpdate.create({ accountId: feePayer.accountId, authorizationKind: 'Signature', incrementNonce: new Bool(true), balanceChange: V2.BalanceChange.negative.fromMINA(2n), preconditions: { account: { nonce: ctx.ledger.getAccount(feePayer.accountId)?.nonce ?? UInt32.zero, }, }, }) ); ctx.add( V2.AccountUpdate.create({ accountId: app.accountId, authorizationKind: 'Signature', useFullCommitment: new Bool(true), implicitAccountCreationFee: new Bool(true), balanceChange: V2.BalanceChange.positive.fromMINA(1n), setVerificationKey: compiledTestProgram.verificationKey, setPermissions: { editState: 'Proof', send: 'Impossible', receive: 'Impossible', setDelegate: 'Impossible', setPermissions: 'Impossible', setVerificationKey: 'Impossible', setZkappUri: 'Impossible', editActionState: 'Impossible', setTokenSymbol: 'Impossible', incrementNonce: 'Proof', setVotingFor: 'Impossible', setTiming: 'Impossible', access: 'None', }, }) ); await TestProgram.init(ctx, app.accountId, Field(3) as never); } ); console.log(JSON.stringify(testTransaction, null, 2));