Gasless SDK (EOA) 3
The new TypeScript Gasless SDK (EOA) is here!
Last updated
Was this helpful?
The new TypeScript Gasless SDK (EOA) is here!
Last updated
Was this helpful?
Changes in the new SDK:
Typescript based SDK
Using event listeners you can monitor the state change of a transaction. One can get notified on transaction hash creation, transaction being mined or on any error.
How to build and send transaction with Ethers:
const provider = await biconomy.provider;
const contractInstance = new ethers.Contract(
config.contract.address,
config.contract.abi,
biconomy.ethersProvider
);
let { data } = await contractInstance.populateTransaction.setQuote(arg);
let txParams = {
data: data,
to: config.contract.address,
from: userAddress,
signatureType: "EIP712_SIGN",
};
await provider.send("eth_sendTransaction", [txParams]);
// Listen to transaction updates:
biconomy.on("txHashGenerated", data: { transactionId: string; transactionHash: string; }) => {
console.log(data);
showSuccessMessage(`tx hash ${data.hash}`);
});
biconomy.on("txMined", (data: {msg: string; id: string; hash: string; receipt: string}) => {
console.log(data);
});
biconomy.on("onError", (data: {error: any; transactionId: string}) => {
console.log(data);
});
bicnomy.on("txHashChanged", (data: {transactionId: string, transactionHash: string}) => {
console.log(data);
});
const provider = await biconomy.provider;
const contractInstance = new ethers.Contract(
config.contract.address,
config.contract.abi,
biconomy.ethersProvider
);
let { data } = await contractInstance.populateTransaction.setQuote(arg);
let txParams = {
data: data,
to: config.contract.address,
from: userAddress,
signatureType: "PERSONAL_SIGN",
};
await provider.send("eth_sendTransaction", [txParams]);
// Listen to transaction updates:
biconomy.on("txHashGenerated", data: { transactionId: string; transactionHash: string; }) => {
console.log(data);
showSuccessMessage(`tx hash ${data.hash}`);
});
biconomy.on("txMined", (data: {msg: string; id: string; hash: string; receipt: string}) => {
console.log(data);
});
biconomy.on("onError", (data: {error: any; transactionId: string}) => {
console.log(data);
});
bicnomy.on("txHashChanged", (data: {transactionId: string, transactionHash: string}) => {
console.log(data);
});
// Getting the signatures based on EIP 712 Signature Scheme:
const domainType = [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "verifyingContract", type: "address" },
{ name: "salt", type: "bytes32" },
];
const metaTransactionType = [
{ name: "nonce", type: "uint256" },
{ name: "from", type: "address" },
{ name: "functionSignature", type: "bytes" },
];
let domainData = {
name: "TestContract",
version: "1",
verifyingContract: config.contract.address,
salt: "0x" + (42).toString(16).padStart(64, "0"),
};
const contractInstance = new ethers.Contract(
config.contract.address,
config.contract.abi as ContractInterface,
signer!
);
let nonce = await contractInstance.getNonce(userAddress);
const contractInterface = new ethers.utils.Interface(config.contract.abi);
let functionSignature = contractInterface.encodeFunctionData("setQuote", [
newQuote,
]);
let message = {
nonce: parseInt(nonce),
from: userAddress,
functionSignature: functionSignature,
};
const dataToSign = JSON.stringify({
types: {
EIP712Domain: domainType,
MetaTransaction: metaTransactionType,
},
domain: domainData,
primaryType: "MetaTransaction",
message: message,
});
let signature = await ethersProvider.send("eth_signTypedData_v3", [
userAddress,
dataToSign,
]);
let { r, s, v } = (signature: any) => {
if (!ethers.utils.isHexString(signature)) {
throw new Error(
'Given value "'.concat(signature, '" is not a valid hex string.')
);
}
const r = signature.slice(0, 66);
const s = "0x".concat(signature.slice(66, 130));
let v = "0x".concat(signature.slice(130, 132));
v = ethers.BigNumber.from(v).toString();
if (![27, 28].includes(Number(v))) v += 27;
return {
r: r,
s: s,
v: Number(v),
};
};
const provider = await biconomy.provider;
let { data } =
await contractInstance.populateTransaction.executeMetaTransaction(
userAddress,
functionData,
r,
s,
v
);
let txParams = {
data: data,
to: contractAddress,
from: userAddress,
signatureType: "EIP712_SIGN",
};
await provider.send("eth_sendTransaction", [txParams]);
// Listen to transaction updates:
biconomy.on("txHashGenerated", data: { transactionId: string; transactionHash: string; }) => {
console.log(data);
showSuccessMessage(`tx hash ${data.hash}`);
});
biconomy.on("txMined", (data: {msg: string; id: string; hash: string; receipt: string}) => {
console.log(data);
});
biconomy.on("onError", (data: {error: any; transactionId: string}) => {
console.log(data);
});
bicnomy.on("txHashChanged", (data: {transactionId: string, transactionHash: string}) => {
console.log(data);
});
const contractInstance = await new web3.eth.Contract(
abi,
contractAddress
);
const nonce = await contractInstance.methods.getNonce(address).call();
let functionSignature = await contractInstance.methods
.setQuote('test')
.encodeABI();
let messageToSign = (
nonce: number,
chainId: number,
functionSignature: string,
contractAddress: string
) => {
return abi.soliditySHA3(
["uint256", "address", "uint256", "bytes"],
[nonce, contractAddress, chainId, toBuffer(functionSignature)]
);
};
const signature = await walletProvider.signMessage(messageToSign);
let { r, s, v } = (signature: any) => {
if (!ethers.utils.isHexString(signature)) {
throw new Error(
'Given value "'.concat(signature, '" is not a valid hex string.')
);
}
const r = signature.slice(0, 66);
const s = "0x".concat(signature.slice(66, 130));
let v = "0x".concat(signature.slice(130, 132));
v = ethers.BigNumber.from(v).toString();
if (![27, 28].includes(Number(v))) v += 27;
return {
r: r,
s: s,
v: Number(v),
};
};
const provider = await biconomy.provider;
let { data } =
await contractInstance.populateTransaction.executeMetaTransaction(
userAddress,
functionData,
r,
s,
v
);
let txParams = {
data: data,
to: config.contract.address,
from: userAddress,
signatureType: "PERSONAL_SIGN",
};
await provider.send("eth_sendTransaction", [txParams]);
// Listen to transaction updates:
biconomy.on("txHashGenerated", data: { transactionId: string; transactionHash: string; }) => {
console.log(data);
showSuccessMessage(`tx hash ${data.hash}`);
});
biconomy.on("txMined", (data: {msg: string; id: string; hash: string; receipt: string}) => {
console.log(data);
});
biconomy.on("onError", (data: {error: any; transactionId: string}) => {
console.log(data);
});
bicnomy.on("txHashChanged", (data: {transactionId: string, transactionHash: string}) => {
console.log(data);
});
How to build and send transactions with Web3:
const web3 = new Web3(biconomy.provider);
const contractInstance = new web3.eth.Contract(
abi
contractAddress
);
await contractInstance.methods.setQuote(newQuote).send({
from: address,
signatureType: "EIP712_SIGN",
});
// Listen to transaction updates:
biconomy.on("txHashGenerated", data: { transactionId: string; transactionHash: string; }) => {
console.log(data);
showSuccessMessage(`tx hash ${data.hash}`);
});
biconomy.on("txMined", (data: {msg: string; id: string; hash: string; receipt: string}) => {
console.log(data);
});
biconomy.on("onError", (data: {error: any; transactionId: string}) => {
console.log(data);
});
bicnomy.on("txHashChanged", (data: {transactionId: string, transactionHash: string}) => {
console.log(data);
});
const web3 = new Web3(biconomy.provider as any);
const contractInstance = new web3.eth.Contract(
config.contract.abi as AbiItem[],
config.contract.address
);
await contractInstance.methods
.setQuote(newQuote)
.send("eth_sendTransaction", {
from: address,
signatureType: "PERSONAL_SIGN",
});
// Listen to transaction updates:
biconomy.on("txHashGenerated", data: { transactionId: string; transactionHash: string; }) => {
console.log(data);
showSuccessMessage(`tx hash ${data.hash}`);
});
biconomy.on("txMined", (data: {msg: string; id: string; hash: string; receipt: string}) => {
console.log(data);
});
biconomy.on("onError", (data: {error: any; transactionId: string}) => {
console.log(data);
});
bicnomy.on("txHashChanged", (data: {transactionId: string, transactionHash: string}) => {
console.log(data);
});
const domainType = [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "verifyingContract", type: "address" },
{ name: "salt", type: "bytes32" },
];
const metaTransactionType = [
{ name: "nonce", type: "uint256" },
{ name: "from", type: "address" },
{ name: "functionSignature", type: "bytes" },
];
let domainData = {
name: "TestContract",
version: "1",
verifyingContract: config.contract.address,
salt: "0x" + (42).toString(16).padStart(64, "0"),
};
const contractInstance = await new web3.eth.Contract(
config.contract.abi as AbiItem[],
config.contract.address
);
const web3 = new Web3(biconomy.provider);
let nonce = await contractInstance.methods.getNonce(address).call();
let functionSignature = await contractInstance.methods
.setQuote(newQuote)
.encodeABI();
let message = {
nonce: parseInt(nonce),
from: address,
functionSignature: functionSignature,
};
const dataToSign = JSON.stringify({
types: {
EIP712Domain: domainType,
MetaTransaction: metaTransactionType,
},
domain: domainData,
primaryType: "MetaTransaction",
message: message,
});
web3.currentProvider.send(
{
jsonrpc: "2.0",
id: 999999999999,
method: "eth_signTypedData_v4",
params: [address, dataToSign],
},
let { r, s, v } = (signature: any) => {
if (!ethers.utils.isHexString(signature)) {
throw new Error(
'Given value "'.concat(signature, '" is not a valid hex string.')
);
}
const r = signature.slice(0, 66);
const s = "0x".concat(signature.slice(66, 130));
let v = "0x".concat(signature.slice(130, 132));
v = ethers.BigNumber.from(v).toString();
if (![27, 28].includes(Number(v))) v += 27;
return {
r: r,
s: s,
v: Number(v),
};
};
const contractInstance = new web3.eth.Contract(
abi
contractAddress
);
await contractInstance.methods
.executeMetaTransaction(userAddress, functionData, r, s, v)
.send({
from: userAddress,
});
// Listen to transaction updates:
biconomy.on("txHashGenerated", data: { transactionId: string; transactionHash: string; }) => {
console.log(data);
showSuccessMessage(`tx hash ${data.hash}`);
});
biconomy.on("txMined", (data: {msg: string; id: string; hash: string; receipt: string}) => {
console.log(data);
});
biconomy.on("onError", (data: {error: any; transactionId: string}) => {
console.log(data);
});
bicnomy.on("txHashChanged", (data: {transactionId: string, transactionHash: string}) => {
console.log(data);
});
const web3 = new Web3(biconomy.provider);
const contractInstance = await new web3.eth.Contract(
abi,
contractAddress
);
const nonce = await contractInstance.methods.getNonce(address).call();
let functionSignature = await contractInstance.methods
.setQuote('test')
.encodeABI();
let messageToSign = (
nonce: number,
chainId: number,
functionSignature: string,
contractAddress: string
) => {
return abi.soliditySHA3(
["uint256", "address", "uint256", "bytes"],
[nonce, contractAddress, chainId, toBuffer(functionSignature)]
);
};
const signature = await walletProvider.signMessage(messageToSign);
const signature = await web3.eth.personal.sign(
"0x" + messageToSign.toString("hex"),
address
);
let { r, s, v } = (signature: any) => {
if (!ethers.utils.isHexString(signature)) {
throw new Error(
'Given value "'.concat(signature, '" is not a valid hex string.')
);
}
const r = signature.slice(0, 66);
const s = "0x".concat(signature.slice(66, 130));
let v = "0x".concat(signature.slice(130, 132));
v = ethers.BigNumber.from(v).toString();
if (![27, 28].includes(Number(v))) v += 27;
return {
r: r,
s: s,
v: Number(v),
};
};
const tx = await contractInstance.methods
.executeMetaTransaction(userAddress, functionData, r, s, v)
.send({
from: userAddress,
});
// Listen to transaction updates:
biconomy.on("txHashGenerated", data: { transactionId: string; transactionHash: string; }) => {
console.log(data);
showSuccessMessage(`tx hash ${data.hash}`);
});
biconomy.on("txMined", (data: {msg: string; id: string; hash: string; receipt: string}) => {
console.log(data);
});
biconomy.on("onError", (data: {error: any; transactionId: string}) => {
console.log(data);
});
bicnomy.on("txHashChanged", (data: {transactionId: string, transactionHash: string}) => {
console.log(data);
});