-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add program counter, fix types issue (#2145)
Co-authored-by: Enes <[email protected]>
- Loading branch information
1 parent
a713b01
commit 0599513
Showing
19 changed files
with
331 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
apps/laboratory/src/components/Solana/SolanaWriteContractTest.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import React, { useState } from 'react' | ||
import { Button, useToast } from '@chakra-ui/react' | ||
import { | ||
SystemProgram, | ||
PublicKey, | ||
Keypair, | ||
Transaction, | ||
TransactionInstruction, | ||
LAMPORTS_PER_SOL | ||
} from '@solana/web3.js' | ||
import { useWeb3ModalAccount, useWeb3ModalProvider } from '@web3modal/solana/react' | ||
|
||
import { COUNTER_ACCOUNT_SIZE } from '../../utils/SolanaConstants' | ||
import { deserializeCounterAccount, detectProgramId } from '../../utils/SolanaUtil' | ||
|
||
export function SolanaWriteContractTest() { | ||
const toast = useToast() | ||
const { address, currentChain } = useWeb3ModalAccount() | ||
const { walletProvider, connection } = useWeb3ModalProvider() | ||
const [loading, setLoading] = useState(false) | ||
|
||
async function onIncrementCounter() { | ||
setLoading(true) | ||
|
||
const PROGRAM_ID = new PublicKey(detectProgramId(currentChain?.chainId ?? '')) | ||
|
||
try { | ||
if (!walletProvider || !address) { | ||
throw new Error('User is disconnected') | ||
} | ||
|
||
if (!connection) { | ||
throw new Error('No connection set') | ||
} | ||
|
||
const counterKeypair = Keypair.generate() | ||
const counter = counterKeypair.publicKey | ||
|
||
const balance = await connection.getBalance(walletProvider.publicKey) | ||
if (balance < LAMPORTS_PER_SOL / 100) { | ||
throw Error('Not enough SOL in wallet') | ||
} | ||
|
||
const allocIx: TransactionInstruction = SystemProgram.createAccount({ | ||
fromPubkey: walletProvider.publicKey, | ||
newAccountPubkey: counter, | ||
lamports: await connection.getMinimumBalanceForRentExemption(COUNTER_ACCOUNT_SIZE), | ||
space: COUNTER_ACCOUNT_SIZE, | ||
programId: PROGRAM_ID | ||
}) | ||
|
||
const incrementIx: TransactionInstruction = new TransactionInstruction({ | ||
programId: PROGRAM_ID, | ||
keys: [ | ||
{ | ||
pubkey: counter, | ||
isSigner: false, | ||
isWritable: true | ||
} | ||
], | ||
data: Buffer.from([0x0]) | ||
}) | ||
|
||
const tx = new Transaction().add(allocIx).add(incrementIx) | ||
|
||
tx.feePayer = walletProvider.publicKey | ||
tx.recentBlockhash = (await connection.getLatestBlockhash('confirmed')).blockhash | ||
|
||
await walletProvider.signAndSendTransaction(tx, [counterKeypair]) | ||
|
||
const counterAccountInfo = await connection.getAccountInfo(counter, { | ||
commitment: 'confirmed' | ||
}) | ||
|
||
if (!counterAccountInfo) { | ||
throw new Error('Expected counter account to have been created') | ||
} | ||
|
||
const counterAccount = deserializeCounterAccount(counterAccountInfo?.data) | ||
|
||
if (counterAccount.count !== 1) { | ||
throw new Error('Expected count to have been 1') | ||
} | ||
|
||
toast({ | ||
title: 'Succcess', | ||
description: `[alloc+increment] count is: ${counterAccount.count}`, | ||
status: 'success', | ||
isClosable: true | ||
}) | ||
} catch (err) { | ||
toast({ | ||
title: 'Transaction failed', | ||
description: 'Failed to increment counter', | ||
status: 'error', | ||
isClosable: true | ||
}) | ||
} finally { | ||
setLoading(false) | ||
} | ||
} | ||
|
||
return ( | ||
<Button isDisabled={loading} data-testid="sign-message-button" onClick={onIncrementCounter}> | ||
Increment Counter With Sign | ||
</Button> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { solana, solanaDevnet, solanaTestnet } from './ChainsUtil' | ||
|
||
export const COUNTER_ACCOUNT_SIZE = 8 | ||
|
||
export const SolanaConstantsUtil = { | ||
// You can add local net in chains if you're using local validator | ||
chains: [solana, solanaTestnet, solanaDevnet], | ||
programIds: [ | ||
{ | ||
chainId: solanaDevnet.chainId, | ||
programId: 'Cb5aXEgXptKqHHWLifvXu5BeAuVLjojQ5ypq6CfQj1hy' | ||
}, | ||
{ | ||
chainId: solanaTestnet.chainId, | ||
programId: 'FZn4xQoKKvcxDADDRdqNAAPnVv9qYCbUTbP3y4Rn1BBr' | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { SolanaConstantsUtil } from './SolanaConstants' | ||
|
||
export function deserializeCounterAccount(data?: Buffer): { count: number } { | ||
if (data?.byteLength !== 8) { | ||
throw Error('Need exactly 8 bytes to deserialize counter') | ||
} | ||
|
||
return { | ||
count: Number(data[0]) | ||
} | ||
} | ||
|
||
export function detectProgramId(chainId: string): string { | ||
return SolanaConstantsUtil.programIds.find(chain => chain.chainId === chainId)?.programId ?? '' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.