// 1. Prepare - get EIP-712 payloads
const prepareResponse = await fetch('https://api.domeapi.io/v1/polymarket/link-prepare', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'linkPrepare',
id: crypto.randomUUID(),
params: {
walletAddress: userWalletAddress,
walletType: 'safe',
autoDeploySafe: true,
},
}),
});
const prepareData = await prepareResponse.json();
if (prepareData.error) {
throw new Error(`Prepare failed: ${prepareData.error.message}`);
}
const { sessionId, eip712Payload, safeDeployPayload, safeInfo } = prepareData.result;
// 2. Sign credentials payload using Privy
const signature = await privy.signTypedData({
walletId,
typedData: eip712Payload,
});
// 3. If Safe needs deployment, sign the deployment payload
let deploymentSignature;
if (safeDeployPayload) {
deploymentSignature = await privy.signTypedData({
walletId,
typedData: safeDeployPayload,
});
}
// 4. Complete - exchange signatures for credentials (and deploy Safe if needed)
const completeResponse = await fetch('https://api.domeapi.io/v1/polymarket/link-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'linkComplete',
id: crypto.randomUUID(),
params: {
sessionId,
signature,
...(deploymentSignature && { deploymentSignature }),
},
}),
});
const completeData = await completeResponse.json();
if (completeData.error) {
throw new Error(`Complete failed: ${completeData.error.message}`);
}
const { credentials, signerAddress, safeAddress, safeDeployed, safeDeployTxHash } = completeData.result;
// 5. Store credentials for future order placement
await database.savePolymarketCredentials(userId, {
apiKey: credentials.apiKey,
apiSecret: credentials.apiSecret,
apiPassphrase: credentials.apiPassphrase,
signerAddress,
safeAddress,
});
if (safeDeployed) {
console.log(`Safe deployed! Transaction: ${safeDeployTxHash}`);
}
// 6. Set allowances if needed
// For freshly deployed Safes, safeTxPayload is included in link-complete response (streamlined flow)
// For existing Safes, call /link-set-allowances-prepare first (standard flow)
const { safeTxPayload: allowancesPayload, allowancesToSet } = completeData.result;
if (allowancesPayload && allowancesToSet?.length > 0) {
// Streamlined flow: safeTxPayload already included in link-complete response
// Sign the messageHash using signMessage (eth_sign)
const allowanceSignature = await privy.signMessage({
walletId,
message: allowancesPayload.messageHash,
});
// Submit - execute the allowance transactions
const allowanceResponse = await fetch('https://api.domeapi.io/v1/polymarket/link-set-allowances', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'setAllowances',
id: crypto.randomUUID(),
params: { sessionId, chainId: 137, allowanceSignature },
}),
});
const allowanceData = await allowanceResponse.json();
console.log('Allowances set:', allowanceData.result.allowancesSet);
console.log('Transaction hash:', allowanceData.result.transactionHash);
} else if (safeInfo && !safeInfo.hasAllowances) {
// Standard flow for existing Safes: call /link-set-allowances-prepare first
const prepareAllowanceResponse = await fetch('https://api.domeapi.io/v1/polymarket/link-set-allowances-prepare', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'setAllowancesPrepare',
id: crypto.randomUUID(),
params: { sessionId, chainId: 137 },
}),
});
const prepareAllowanceData = await prepareAllowanceResponse.json();
const { safeTxPayload, allowancesToSet: toSet } = prepareAllowanceData.result;
if (toSet.length > 0) {
const allowanceSignature = await privy.signMessage({
walletId,
message: safeTxPayload.messageHash,
});
const allowanceResponse = await fetch('https://api.domeapi.io/v1/polymarket/link-set-allowances', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'setAllowances',
id: crypto.randomUUID(),
params: { sessionId, chainId: 137, allowanceSignature },
}),
});
const allowanceData = await allowanceResponse.json();
console.log('Allowances set:', allowanceData.result.allowancesSet);
console.log('Transaction hash:', allowanceData.result.transactionHash);
}
}
console.log('Safe wallet linked successfully!');