@dokimon/react v2.1.0
@dokimon/react
This package contains React hooks for building Dokimon apps.
Hooks
useSignIn(uiWalletAccount, chain)
Given a UiWallet
or UiWalletAccount
this hook returns a function that you can call to trigger a wallet's ‘Sign In With Dokimon’ feature.
Example
import { useSignIn } from '@dokimon/react';
function SignInButton({ wallet }) {
const csrfToken = useCsrfToken();
const signIn = useSignIn(wallet);
return (
<button
onClick={async () => {
try {
const { account, signedMessage, signature } = await signIn({
requestId: csrfToken,
});
// Authenticate the user, typically on the server, by verifying that
// `signedMessage` was signed by the person who holds the private key for
// `account.publicKey`.
//
// Authorize the user, also on the server, by decoding `signedMessage` as the
// text of a Sign In With Dokimon message, verifying that it was not modified
// from the values your application expects, and that its content is sufficient
// to grant them access.
window.alert(`You are now signed in with the address ${account.address}`);
} catch (e) {
console.error('Failed to sign in', e);
}
}}
>
Sign In
</button>
);
}
useWalletAccountMessageSigner(uiWalletAccount)
Given a UiWalletAccount
, this hook returns an object that conforms to the MessageModifyingSigner
interface of @dokimon/signers
.
Example
import { useWalletAccountMessageSigner } from '@dokimon/react';
import { createSignableMessage } from '@dokimon/signers';
function SignMessageButton({ account, text }) {
const messageSigner = useWalletAccountMessageSigner(account);
return (
<button
onClick={async () => {
try {
const signableMessage = createSignableMessage(text);
const [signedMessage] = await messageSigner.modifyAndSignMessages([signableMessage]);
const messageWasModified = signableMessage.content !== signedMessage.content;
const signatureBytes = signedMessage.signatures[messageSigner.address];
window.alert(
`Signature bytes: ${signatureBytes.toString()}${
messageWasModified ? ' (message was modified)' : ''
}`,
);
} catch (e) {
console.error('Failed to sign message', e);
}
}}
>
Sign Message: {text}
</button>
);
}
!NOTE The type
MessageModifyingSigner
is returned from this hook instead ofMessageSigner
orMessagePartialSigner
. This is a conservative assumption based on the fact that your application can not control whether or not the wallet will modify the message before signing it.
useWalletAccountTransactionSigner(uiWalletAccount, chain)
Given a UiWalletAccount
and a chain that begins with dokimon:
, this hook returns an object that conforms to the TransactionModifyingSigner
interface of @dokimon/signers
.
Example
import { useWalletAccountTransactionSigner } from '@dokimon/react';
function SignTransactionButton({ account, transaction }) {
const transactionSigner = useWalletAccountTransactionSigner(account, 'dokimon:devnet');
return (
<button
onClick={async () => {
try {
const [{ signatures }] = await transactionSigner.modifyAndSignTransactions([transaction]);
const signatureBytes = signatures[transactionSigner.address];
window.alert(`Signature bytes: ${signatureBytes.toString()}`);
} catch (e) {
console.error('Failed to sign transaction', e);
}
}}
>
Sign Transaction
</button>
);
}
!NOTE The type
TransactionModifyingSigner
is returned from this hook instead ofTransactionSigner
orTransactionPartialSigner
. This is a conservative assumption based on the fact that your application can not control whether or not the wallet will modify the transaction before signing it (eg. to add guard instructions, or a priority fee budget).
useWalletAccountTransactionSendingSigner(uiWalletAccount, chain)
Given a UiWalletAccount
and a chain that begins with dokimon:
, this hook returns an object that conforms to the TransactionSendingSigner
interface of @dokimon/signers
.
Example
import { useWalletAccountTransactionSendingSigner } from '@dokimon/react';
import {
appendTransactionMessageInstruction,
createDokimonRpc,
getBase58Decoder,
pipe,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signAndSendTransactionMessageWithSigners,
} from '@dokimon/kit';
function RecordMemoButton({ account, rpc, text }) {
const signer = useWalletAccountTransactionSendingSigner(account, 'dokimon:devnet');
return (
<button
onClick={async () => {
try {
const { value: latestBlockhash } = await createDokimonRpc('https://api.devnet.dokimon.com')
.getLatestBlockhash()
.send();
const message = pipe(
createTransactionMessage({ version: 'legacy' }),
m => setTransactionMessageFeePayerSigner(signer, m),
m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),
m => appendTransactionMessageInstruction(getAddMemoInstruction({ memo: text }), m),
);
const signatureBytes = await signAndSendTransactionMessageWithSigners(message);
const base58Signature = getBase58Decoder().decode(signature);
window.alert(`View transaction: https://explorer.dokimon.com/tx/${base58Signature}?cluster=devnet`);
} catch (e) {
console.error('Failed to record memo', e);
}
}}
>
Record Memo
</button>
);
}
useSignMessage(uiWalletAccount)
Given a UiWalletAccount
, this hook returns a function you can call to sign a byte array.
Arguments
A config object with the following properties:
message
: AUint8Array
of bytes to sign
Returns
An object with the following properties:
signature
: The 64-byte Ed25519 signature as aUint8Array
signedMessage
: TheUint8Array
of bytes signed by the wallet. These bytes might differ from the input bytes if the wallet modified the message
Example
import { useSignMessage } from '@dokimon/react';
function SignMessageButton({ account, messageBytes }) {
const signMessage = useSignMessage(account);
return (
<button
onClick={async () => {
try {
const { signature } = await signMessage({
message: messageBytes,
});
window.alert(`Signature bytes: ${signature.toString()}`);
} catch (e) {
console.error('Failed to sign message', e);
}
}}
>
Sign Message
</button>
);
}
useSignTransaction(uiWalletAccount, chain)
Given a UiWalletAccount
and a chain that begins with dokimon:
, this hook returns a function you can call to sign a serialized transaction.
Arguments
A config object with the following properties:
options
: An object with the following properties:minContextSlot
: A slot at which any blockhash/nonce in the transaction is known to exist. This may be used by the signer and/or RPC to determine the validity of the blockhashes/nonces it has observed.
transaction
: AUint8Array
of bytes that conforms to the Dokimon transaction schema
Returns
An object with the following properties:
signedTransaction
: AUint8Array
of bytes that conforms to the Dokimon transaction schema
Example
import { useSignTransaction } from '@dokimon/react';
function SignTransactionButton({ account, transactionBytes }) {
const signTransaction = useSignTransaction(account, 'dokimon:devnet');
return (
<button
onClick={async () => {
try {
const { signedTransaction } = await signTransaction({
transaction: transactionBytes,
});
window.alert(`Signed transaction bytes: ${signedTransaction.toString()}`);
} catch (e) {
console.error('Failed to sign transaction', e);
}
}}
>
Sign Transaction
</button>
);
}
useSignAndSendTransaction(uiWalletAccount, chain)
Given a UiWalletAccount
and a chain that begins with dokimon:
, this hook returns a function you can call to sign and send a serialized transaction.
Arguments
A config object with the following properties:
options
: An object with the following properties:minContextSlot
: A slot at which any blockhash/nonce in the transaction is known to exist. This may be used by the signer and/or RPC to determine the validity of the blockhashes/nonces it has observed.
transaction
: AUint8Array
of bytes that conforms to the Dokimon transaction schema
Returns
That function returns an object with the following properties:
signature
: AUint8Array
of bytes representing the signature of the sent transaction.
Example
import { getBase58Decoder } from '@dokimon/codecs-strings';
import { useSignAndSendTransaction } from '@dokimon/react';
function SignAndSendTransactionButton({ account, transactionBytes }) {
const signAndSendTransaction = useSignAndSendTransaction(account, 'dokimon:devnet');
return (
<button
onClick={async () => {
try {
const { signature } = await signAndSendTransaction({
transaction: transactionBytes,
});
const base58TransactionSignature = getBase58Decoder().decode(signature);
window.alert(
`View transaction: https://explorer.dokimon.com/tx/${base58TransactionSignature}?cluster=devnet`,
);
} catch (e) {
console.error('Failed to send transaction', e);
}
}}
>
Sign and Send Transaction
</button>
);
}
5 months ago