Skip to content

[do not merge] #393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/deployer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"@turnkey/sdk-server": "workspace:*",
"@turnkey/ethers": "workspace:*",
"dotenv": "^16.0.3",
"ethers": "^6.10.0",
"ethers": "^6.13.0",
"solc": "0.8.13"
}
}
2 changes: 1 addition & 1 deletion examples/sweeper/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"@turnkey/ethers": "workspace:*",
"@uniswap/sdk-core": "^3.1.1",
"dotenv": "^16.0.3",
"ethers": "^6.10.0",
"ethers": "^6.13.0",
"hardhat": "^2.12.7",
"prompts": "^2.4.2"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/trading-runner/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@uniswap/v3-core": "^1.0.1",
"@uniswap/v3-sdk": "^3.9.0",
"dotenv": "^16.0.3",
"ethers": "^6.10.0",
"ethers": "^6.13.0",
"jsbi": "^3.2.5",
"prompts": "^2.4.2"
},
Expand Down
8 changes: 7 additions & 1 deletion examples/with-ethers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
"scripts": {
"start": "tsx src/index.ts",
"start-advanced": "tsx src/advanced.ts",
"start-blobs": "tsx src/blobs.ts",
"start-sepolia-legacy": "tsx src/sepoliaLegacyTx.ts",
"clean": "rimraf ./dist ./.cache",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@chainsafe/bls": "^8.1.0",
"@chainsafe/blst": "^2.2.0",
"@turnkey/api-key-stamper": "workspace:*",
"@turnkey/encoding": "workspace:*",
"@turnkey/ethers": "workspace:*",
"@turnkey/http": "workspace:*",
"@turnkey/sdk-server": "workspace:*",
"bls": "link:@chainsafe/bls/bls",
"dotenv": "^16.0.3",
"ethers": "^6.10.0",
"ethers": "^6.13.0",
"kzg-wasm": "^0.5.0",
"prompts": "^2.4.2"
},
"devDependencies": {
Expand Down
97 changes: 73 additions & 24 deletions examples/with-ethers/src/advanced.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import * as dotenv from "dotenv";
dotenv.config({ path: path.resolve(process.cwd(), ".env.local") });

import { TurnkeySigner } from "@turnkey/ethers";
import { ethers } from "ethers";
import { TurnkeyClient } from "@turnkey/http";
import { ApiKeyStamper } from "@turnkey/api-key-stamper";
import { ethers, Transaction, Signature } from "ethers";
import { Turnkey as TurnkeyServerSDK } from "@turnkey/sdk-server";
import { createNewWallet } from "./createNewWallet";
import { print, assertEqual } from "./util";

async function main() {
if (!process.env.SIGN_WITH) {
Expand All @@ -17,25 +17,24 @@ async function main() {
return;
}

const turnkeyClient = new TurnkeyClient(
{
baseUrl: process.env.BASE_URL!,
},
new ApiKeyStamper({
apiPublicKey: process.env.API_PUBLIC_KEY!,
apiPrivateKey: process.env.API_PRIVATE_KEY!,
})
);
console.log("process base url", process.env.BASE_URL);

const turnkeyClient = new TurnkeyServerSDK({
apiBaseUrl: process.env.BASE_URL!,
apiPrivateKey: process.env.API_PRIVATE_KEY!,
apiPublicKey: process.env.API_PUBLIC_KEY!,
defaultOrganizationId: process.env.ORGANIZATION_ID!,
});

// Initialize a Turnkey Signer
const turnkeySigner = new TurnkeySigner({
client: turnkeyClient,
client: turnkeyClient.apiClient(),
organizationId: process.env.ORGANIZATION_ID!,
signWith: process.env.SIGN_WITH!,
});

// Bring your own provider (such as Alchemy or Infura: https://docs.ethers.org/v6/api/providers/)
const network = "goerli";
const network = "sepolia";
const provider = new ethers.InfuraProvider(network);
const connectedSigner = turnkeySigner.connect(provider);
const address = await connectedSigner.getAddress();
Expand Down Expand Up @@ -95,19 +94,69 @@ async function main() {

print("Turnkey-powered signature - typed data (EIP-712):", `${signature}`);
assertEqual(recoveredAddress, address);

// 4. Sign type 3 (EIP-4844) transaction
const feeEstimate = await connectedSigner.provider?.getFeeData();
console.log("fee estimate", feeEstimate);

const unsignedTx = Transaction.from({
to: "0x08d2b0a37F869FF76BACB5Bab3278E26ab7067B7",
value: 1111,
type: 3,
chainId: 11155111,
gasLimit: 21000,
maxFeePerGas: feeEstimate!.maxFeePerGas,
maxPriorityFeePerGas: feeEstimate!.maxPriorityFeePerGas,
maxFeePerBlobGas: feeEstimate!.maxFeePerGas,
// blobs: [],
blobVersionedHashes: [
"0x01000000000000000000000000000000000000000000000000000000000000aa",
],
});

const gasEstimate = await connectedSigner.estimateGas(unsignedTx);
console.log("gas estimate", gasEstimate);

console.log("serialized unsigned", unsignedTx.unsignedSerialized);
console.log("full tx", unsignedTx.gasLimit);

const signedTx = await connectedSigner.signTransaction(unsignedTx);

console.log("signed tx", signedTx);

const sentTx = await connectedSigner.sendTransaction(unsignedTx);
console.log("sent tx", sentTx);

// console.log({
// unsignedTx,
// unsignedTxTo: unsignedTx.to,
// unsignedTxSerialized: unsignedTx.unsignedSerialized,
// });

// const signedMessage = await connectedSigner.signMessage(
// unsignedTx.unsignedSerialized
// );

// console.log({
// unsignedTx,
// signedMessage,
// });

// const signedTx = Object.assign({}, unsignedTx);

// signedTx.signature = Signature.from(signedMessage);

// console.log({ signedTx });

// // Combine the signautre + transaction
// const broadcastedTx = await connectedSigner.provider?.broadcastTransaction(
// signedTx.serialized
// );

// print("Successfully broadcasted EIP-4844 transaction!", broadcastedTx?.hash!);
}

main().catch((error) => {
console.error(error);
process.exit(1);
});

function print(header: string, body: string): void {
console.log(`${header}\n\t${body}\n`);
}

function assertEqual<T>(left: T, right: T) {
if (left !== right) {
throw new Error(`${JSON.stringify(left)} !== ${JSON.stringify(right)}`);
}
}
150 changes: 150 additions & 0 deletions examples/with-ethers/src/blobs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import * as path from "path";
import * as dotenv from "dotenv";

// Load environment variables from `.env.local`
dotenv.config({ path: path.resolve(process.cwd(), ".env.local") });

import { TurnkeySigner } from "@turnkey/ethers";
import { ethers, Transaction } from "ethers";
import { Turnkey as TurnkeyServerSDK } from "@turnkey/sdk-server";
import { createNewWallet } from "./createNewWallet";
import { print } from "./util";
import {
uint8ArrayFromHexString,
uint8ArrayToHexString,
} from "@turnkey/encoding";

import { loadKZG } from "kzg-wasm";
// import bls from "@chainsafe/bls";
// import { Blob } from "@chainsafe/bls/bls";

async function main() {
if (!process.env.SIGN_WITH) {
// If you don't specify a `SIGN_WITH`, we'll create a new wallet for you via calling the Turnkey API.
await createNewWallet();
return;
}

console.log("process base url", process.env.BASE_URL);

const turnkeyClient = new TurnkeyServerSDK({
apiBaseUrl: process.env.BASE_URL!,
apiPrivateKey: process.env.API_PRIVATE_KEY!,
apiPublicKey: process.env.API_PUBLIC_KEY!,
defaultOrganizationId: process.env.ORGANIZATION_ID!,
});

// Initialize a Turnkey Signer
const turnkeySigner = new TurnkeySigner({
client: turnkeyClient.apiClient(),
organizationId: process.env.ORGANIZATION_ID!,
signWith: process.env.SIGN_WITH!,
});

// Bring your own provider (such as Alchemy or Infura: https://docs.ethers.org/v6/api/providers/)
const network = "sepolia";
const provider = new ethers.InfuraProvider(network);
const connectedSigner = turnkeySigner.connect(provider);
const address = await connectedSigner.getAddress();

print("Address:", address);

// 4. Sign type 3 (EIP-4844) transaction
const feeEstimate = await connectedSigner.provider?.getFeeData();
console.log("fee estimate", feeEstimate);

// Blob stuff
// Create blob data (example with zeros)
const blobData = new Uint8Array(131072).fill(0);

// Create KZG proof and commitment
// Create versioned hash
// const versionByte = new Uint8Array([1]); // 0x01 for version
// const commitmentBytes = hexToBytes(commitment);
// const versionedCommitment = new Uint8Array([...versionByte, ...commitmentBytes]);
// const versionedHash = ethers.utils.keccak256(versionedCommitment);
const kzg = await loadKZG();

// const blob = Blob.fromBytes(blobData);
const blob = uint8ArrayToHexString(blobData);
const commitment = kzg.blobToKZGCommitment(blob);
const proof = kzg.computeBlobKZGProof(blob, commitment);

// // Create versioned hash
const versionByte = new Uint8Array([1]); // 0x01 for version
const commitmentBytes = uint8ArrayFromHexString(commitment);
const versionedCommitment = new Uint8Array([
...versionByte,
...commitmentBytes,
]);
const versionedHash = ethers.keccak256(versionedCommitment);

const unsignedTx = Transaction.from({
to: "0x08d2b0a37F869FF76BACB5Bab3278E26ab7067B7",
value: 1,
type: 3,
chainId: 11155111,
gasLimit: 21000,
maxFeePerGas: feeEstimate!.maxFeePerGas,
maxPriorityFeePerGas: feeEstimate!.maxPriorityFeePerGas,
maxFeePerBlobGas: feeEstimate!.maxFeePerGas,
// blobs: [],
blobVersionedHashes: [versionedHash],
});

// The blobs, commitments, and proofs are sent separately
// const blobSidecar = {
// blobs: [blob],
// commitments: [commitmentBytes],
// proofs: [uint8ArrayFromHexString(proof)],
// };

const gasEstimate = await connectedSigner.estimateGas(unsignedTx);
console.log("gas estimate", gasEstimate);

console.log("serialized unsigned", unsignedTx.unsignedSerialized);
console.log("full tx", unsignedTx.gasLimit);

const signedTx = await connectedSigner.signTransaction(unsignedTx);

console.log("signed tx", signedTx);

const sentTx = await connectedSigner.sendTransaction({
...unsignedTx,
// ...blobSidecar,
});
console.log("sent tx", sentTx);

// console.log({
// unsignedTx,
// unsignedTxTo: unsignedTx.to,
// unsignedTxSerialized: unsignedTx.unsignedSerialized,
// });

// const signedMessage = await connectedSigner.signMessage(
// unsignedTx.unsignedSerialized
// );

// console.log({
// unsignedTx,
// signedMessage,
// });

// const signedTx = Object.assign({}, unsignedTx);

// signedTx.signature = Signature.from(signedMessage);

// console.log({ signedTx });

// // Combine the signautre + transaction
// const broadcastedTx = await connectedSigner.provider?.broadcastTransaction(
// signedTx.serialized
// );

// print("Successfully broadcasted EIP-4844 transaction!", broadcastedTx?.hash!);
}

main().catch((error) => {
console.error(error);
process.exit(1);
});
2 changes: 1 addition & 1 deletion examples/with-ethers/src/createNewWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export async function createNewWallet() {

try {
const turnkeyClient = new TurnkeySDKServer({
apiBaseUrl: "https://api.turnkey.com",
apiBaseUrl: process.env.BASE_URL!,
apiPublicKey: process.env.API_PUBLIC_KEY!,
apiPrivateKey: process.env.API_PRIVATE_KEY!,
defaultOrganizationId: process.env.ORGANIZATION_ID!,
Expand Down
2 changes: 1 addition & 1 deletion examples/with-uniswap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@uniswap/v3-core": "^1.0.1",
"@uniswap/v3-sdk": "^3.9.0",
"dotenv": "^16.0.3",
"ethers": "^6.10.0",
"ethers": "^6.13.0",
"hardhat": "^2.12.7",
"jsbi": "^3.2.5"
}
Expand Down
1 change: 1 addition & 0 deletions examples/with-viem/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@turnkey/sdk-server": "workspace:*",
"@turnkey/viem": "workspace:*",
"dotenv": "^16.0.3",
"ethers": "6.13.0",
"fetch": "^1.1.0",
"prompts": "^2.4.2",
"typescript": "5.1",
Expand Down
Loading
Loading