| Code Coverage
| Lines | Functions and Methods | Classes and Traits
Total | 91.67% covered (success) | 91.67% | 33 / 36 | 0.00% covered (danger) | 0.00% | 0 / 1 | CRAP | 0.00% covered (danger) | 0.00% | 0 / 1
SPLTokenActions | 91.67% covered (success) | 91.67% | 33 / 36 | 0.00% covered (danger) | 0.00% | 0 / 1 | 8.04 | 0.00% covered (danger) | 0.00% | 0 / 1
getOrCreateAssociatedTokenAccount | 91.67% covered (success) | 91.67% | 33 / 36 | 0.00% covered (danger) | 0.00% | 0 / 1 | 8.04 |

1 | <?php
2 |
3 | namespace Attestto\SolanaPhpSdk\Programs\SplToken\Actions;
4 |
5 | use Attestto\SolanaPhpSdk\Connection;
6 | use Attestto\SolanaPhpSdk\Exceptions\AccountNotFoundException;
7 | use Attestto\SolanaPhpSdk\Exceptions\GenericException;
8 | use Attestto\SolanaPhpSdk\Exceptions\InputValidationException;
9 | use Attestto\SolanaPhpSdk\Exceptions\InvalidIdResponseException;
10 | use Attestto\SolanaPhpSdk\Exceptions\MethodNotFoundException;
11 | use Attestto\SolanaPhpSdk\Exceptions\TokenInvalidAccountOwnerError;
12 | use Attestto\SolanaPhpSdk\Exceptions\TokenInvalidMintError;
13 | use Attestto\SolanaPhpSdk\Exceptions\TokenOwnerOffCurveError;
14 | use Attestto\SolanaPhpSdk\Keypair;
15 | use Attestto\SolanaPhpSdk\Programs\SplToken\State\Account;
16 | use Attestto\SolanaPhpSdk\PublicKey;
17 | use Attestto\SolanaPhpSdk\Transaction;
18 | use Attestto\SolanaPhpSdk\Util\Commitment;
19 | use Attestto\SolanaPhpSdk\Util\ConfirmOptions;
20 | use Attestto\SolanaPhpSdk\Util\Signer;
21 | use Exception;
22 | use Psr\Http\Client\ClientExceptionInterface;
23 | use function Attestto\SolanaPhpSdk\Programs\SplToken\getAccount;
24 |
25 | trait SPLTokenActions {
26 |
27 | /**
28 | * @param Connection $connection
29 | * @param Signer|Keypair $payer
30 | * @param PublicKey $mint
31 | * @param PublicKey $owner
32 | * @param boolean $allowOwnerOffCurve
33 | * @param Commitment|null $commitment
34 | * @param ConfirmOptions $confirmOptions
35 | * @param PublicKey $programId
36 | * @param PublicKey $associatedTokenProgramId
37 | * @return mixed
38 | * @throws AccountNotFoundException
39 | * @throws ClientExceptionInterface
40 | * @throws InputValidationException
41 | * @throws TokenInvalidAccountOwnerError
42 | * @throws TokenInvalidMintError
43 | * @throws TokenOwnerOffCurveError
44 | * @throws GenericException
45 | * @throws InvalidIdResponseException
46 | * @throws MethodNotFoundException
47 | * @throws \SodiumException
48 | */
49 | public function getOrCreateAssociatedTokenAccount(
50 | Connection $connection,
51 | mixed $payer,
52 | PublicKey $mint,
53 | PublicKey $owner,
54 | bool $allowOwnerOffCurve = true,
55 | Commitment $commitment = null,
56 | ConfirmOptions $confirmOptions = null,
57 | PublicKey $programId = new PublicKey(self::TOKEN_PROGRAM_ID),
58 | PublicKey $associatedTokenProgramId = new PublicKey(self::ASSOCIATED_TOKEN_PROGRAM_ID)
59 | ): Account
60 | {
61 |
62 | $associatedToken = $this->getAssociatedTokenAddressSync(
63 | $mint,
64 | $owner,
65 | $allowOwnerOffCurve,
66 | $programId,
67 | $associatedTokenProgramId
68 | );
69 | $ata = $associatedToken->toBase58();
70 | try {
71 | $account = Account::getAccount($connection, $associatedToken, $commitment, $programId);
72 | } catch (Exception $error) {
73 | if ($error instanceof AccountNotFoundException || $error instanceof TokenInvalidAccountOwnerError) {
74 | try {
75 | $transaction = new Transaction();
76 | $transaction->add(
77 | $this->createAssociatedTokenAccountInstruction(
78 | $payer->getPublicKey(),
79 | $associatedToken,
80 | $owner,
81 | $mint,
82 | $programId,
83 | $associatedTokenProgramId
84 | )
85 | );
86 | if (!$confirmOptions) $confirmOptions = new ConfirmOptions();
87 | $transaction->feePayer = $payer->getPublicKey();
88 | $txnHash = $connection->sendTransaction( $transaction, [$payer]);
89 | } catch (Exception $error) {
90 | // Ignore all errors
91 | // Account Exists but is not funded
92 | throw $error;
93 | }
94 |
95 | $account = Account::getAccount($connection, $associatedToken, $commitment, $programId);
96 | } else {
97 | throw $error;
98 | }
99 | }
100 |
101 | if ($account->mint != $mint) throw new TokenInvalidMintError(
102 | $account->mint->toBase58() . ' != ' . $mint->toBase58()
103 | );
104 | if ($account->owner != $owner) throw new TokenInvalidAccountOwnerError(
105 | $account->owner->toBase58() . ' != ' . $owner->toBase58()
106 | );
107 |
108 | return $account;
109 | }
110 |
111 |
112 |
113 |
114 |
115 | }