Using the txn variable obtained from previous steps. We use the jsonToSign field and sign it as a personal signMessage using Phantom wallet.
Phantom / Solana do not allow message signatures > ~1000 bytes. To workaround this, we allow signing the SHA256 hash of the JSON in cases where payload.jsonToSign.length > 1000.
constgetProvider= () => {if ('phantom'in window) {constphantomWindow= window asany;constprovider=phantomWindow.phantom?.solana;if (provider?.isPhantom) {return provider; }window.open('https://phantom.app/','_blank'); }};constsignTxn=async (context:TxContext, payload:TransactionPayload, simulate:boolean) => {if (!account) thrownewError('Account not found.');let sig ='';if (!simulate) {//Phantom has a weird error where messages must be < ~1000 bytes//If we are within limit, we can have user sign the JSON//Else, we hash the JSON and have user sign the hashconstnormalMessage=payload.jsonToSign.length<1000;let message =payload.jsonToSign;let encodedMessage =newTextEncoder().encode(message);if (!normalMessage) { message =payload.jsonToSign;constsha256Message=CryptoJS.SHA256(message).toString(); encodedMessage =newTextEncoder().encode(sha256Message); }constsignedMessage=awaitgetProvider().request({ method:'signMessage', params: { message: encodedMessage, display:'utf8' } }); sig =signedMessage.signature.toString('hex'); }//We need to pass in solAddress manually hereconsttxBody=createTxBroadcastBody(context, payload, sig, address);return txBody;};