Message Signing
For signing messages (personal signatures), encode your data as base64:TypeScript
const personalSign = async (data: string) => {
// Encode message as base64
const message = Buffer.from(data, 'utf-8').toString('base64');
const body = { message_base64: message };
return await fetch('/v2/wallet/sign/message', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
'X-Magic-Chain': 'ETH'
},
body: JSON.stringify(body)
});
};
Data Signing
For signing transaction data or other structured data, provide a keccak256 hash:import { typedSignatureHash } from '@metamask/eth-sig-util';
const signTypedDataV1 = async (data: TypedDataV1) => {
// Compute hash for typed data V1
const rawDataHash = typedSignatureHash(data);
const body = { raw_data_hash: rawDataHash };
return await fetch('/v2/wallet/sign/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
'X-Magic-Chain': 'ETH'
},
body: JSON.stringify(body)
});
};
import {
MessageTypes,
SignTypedDataVersion,
TypedDataUtils,
TypedMessage,
} from '@metamask/eth-sig-util';
const computeEip712Hash = (
data: TypedMessage<MessageTypes>,
version: SignTypedDataVersion.V3 | SignTypedDataVersion.V4,
): string => {
const hashBuffer = TypedDataUtils.eip712Hash(data, version);
return '0x' + hashBuffer.toString('hex');
};
const signTypedDataV3 = async (data: TypedMessage<MessageTypes>) => {
// Compute EIP-712 hash for typed data V3
const rawDataHash = computeEip712Hash(data, SignTypedDataVersion.V3);
const body = { raw_data_hash: rawDataHash };
return await fetch('/v2/wallet/sign/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
'X-Magic-Chain': 'ETH'
},
body: JSON.stringify(body)
});
};
const signTypedDataV4 = async (data: TypedMessage<MessageTypes>) => {
// Compute EIP-712 hash for typed data V4
const rawDataHash = computeEip712Hash(data, SignTypedDataVersion.V4);
const body = { raw_data_hash: rawDataHash };
return await fetch('/v2/wallet/sign/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
'X-Magic-Chain': 'ETH'
},
body: JSON.stringify(body)
});
};
import { resolveProperties, Signature, Transaction, TransactionLike, TransactionRequest } from 'ethers';
const signTransaction = async (tx: TransactionRequest) => {
// Resolve any promises in transaction properties
const resolvedTx = await resolveProperties(tx);
const txForSigning = { ...resolvedTx };
delete txForSigning.from;
// Create transaction object and get unsigned hash
const btx = Transaction.from(txForSigning as TransactionLike);
const body = { raw_data_hash: btx.unsignedHash };
const res = await fetch('/v2/wallet/sign/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
'X-Magic-Chain': 'ETH'
},
body: JSON.stringify(body)
});
const { r, s, v } = await res.json();
// Attach signature to transaction
btx.signature = Signature.from({ r, s, v });
return btx.serialized;
};