Skip to content

Commit

Permalink
feedback: share signature, signatures, and signed transaction getters
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewkmin committed Sep 13, 2024
1 parent bdded80 commit ccc9a93
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 314 deletions.
2 changes: 0 additions & 2 deletions .changeset/gentle-wolves-burn.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@
Support awaiting consensus

- Add a few new helper functions:
- `getSignatureFromActivity` returns the signature corresponding to a completed activity
- `getSignedTransactionFromActivity` returns the signed transaction corresponding to a completed activity
- `serializeSignature` serializes a raw signature
2 changes: 0 additions & 2 deletions .changeset/heavy-cars-guess.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,5 @@ Support awaiting consensus and improve error handling
- `TurnkeyConsensusNeededError` wraps consensus-related errors
- `TurnkeyActivityError` wraps base Turnkey errors
- Add a few new helper functions:
- `getSignatureFromActivity` returns the signature corresponding to a completed activity
- `getSignedTransactionFromActivity` returns the signed transaction corresponding to a completed activity
- `serializeSignature` serializes a raw signature
- `isTurnkeyActivityConsensusNeededError` and `isTurnkeyActivityError` use `error.walk` to check the type of a Viem error
4 changes: 3 additions & 1 deletion .changeset/tasty-feet-provide.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

Add new helpers and update types and errors

- `getSignatureFromActivity` returns the signature corresponding to a completed activity
- `getSignedTransactionFromActivity` returns the signed transaction corresponding to a completed activity
- `checkActivityStatus` checks the state of an activity and throws an error if the activity either requires consensus or is otherwise not yet completed
- `TERMINAL_ACTIVITY_STATUSES` is a const containing all terminal activity statuses. Useful for checking on an activity
- `TurnkeyActivityError` now uses `undefined` instead of `null`
- Export some additional types: `TActivityId`, `TActivityStatus`, `TActivityType`
- Export some additional types: `TActivity`, `TActivityId`, `TActivityStatus`, `TActivityType`
55 changes: 35 additions & 20 deletions examples/with-ethers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import { ethers } from "ethers";
dotenv.config({ path: path.resolve(process.cwd(), ".env.local") });

import {
getSignatureFromActivity,
getSignedTransactionFromActivity,
TurnkeyActivityConsensusNeededError,
TERMINAL_ACTIVITY_STATUSES,
TActivity,
} from "@turnkey/http";
import { TurnkeySigner, serializeSignature } from "@turnkey/ethers";
import { Turnkey as TurnkeyServerSDK } from "@turnkey/sdk-server";
Expand Down Expand Up @@ -83,11 +86,12 @@ async function main() {
signature = await connectedSigner.signMessage(message);
} catch (error: any) {
signature = await handleActivityError(error).then(
async (activityId: string) => {
const rawSignature = await connectedSigner.getSignatureFromActivity(
activityId
);
return serializeSignature(rawSignature);
async (activity?: TActivity) => {
if (!activity) {
throw error;
}

return serializeSignature(getSignatureFromActivity(activity));
}
);
}
Expand Down Expand Up @@ -124,10 +128,12 @@ async function main() {
signedTx = await connectedSigner.signTransaction(transactionRequest);
} catch (error: any) {
signedTx = await handleActivityError(error).then(
async (activityId: string) => {
return await connectedSigner.getSignedTransactionFromActivity(
activityId
);
async (activity?: TActivity) => {
if (!activity) {
throw error;
}

return getSignedTransactionFromActivity(activity);
}
);
}
Expand Down Expand Up @@ -162,11 +168,14 @@ async function main() {
sentTx = await connectedSigner.sendTransaction(transactionRequest);
} catch (error: any) {
sentTx = await handleActivityError(error).then(
async (activityId: string) => {
const signedTx = await connectedSigner.getSignedTransactionFromActivity(
activityId
async (activity?: TActivity) => {
if (!activity) {
throw error;
}

return await connectedSigner.provider?.broadcastTransaction(
getSignedTransactionFromActivity(activity)
);
return await connectedSigner.provider?.broadcastTransaction(signedTx);
}
);
}
Expand Down Expand Up @@ -206,10 +215,14 @@ async function main() {
});
} catch (error: any) {
depositTx = await handleActivityError(error).then(
async (activityId: string) => {
const signedTx =
await connectedSigner.getSignedTransactionFromActivity(activityId);
return await connectedSigner.provider?.broadcastTransaction(signedTx);
async (activity?: TActivity) => {
if (!activity) {
throw error;
}

return await connectedSigner.provider?.broadcastTransaction(
getSignedTransactionFromActivity(activity)
);
}
);
}
Expand All @@ -224,6 +237,7 @@ async function main() {
if (error instanceof TurnkeyActivityConsensusNeededError) {
const activityId = error["activityId"]!;
let activityStatus = error["activityStatus"]!;
let activity: TActivity | undefined;

while (!TERMINAL_ACTIVITY_STATUSES.includes(activityStatus)) {
console.log("\nWaiting for consensus...\n");
Expand All @@ -242,17 +256,18 @@ async function main() {
}

// Refresh activity status
activityStatus = (
activity = (
await turnkeyClient.apiClient().getActivity({
activityId,
organizationId: process.env.ORGANIZATION_ID!,
})
).activity.status;
).activity;
activityStatus = activity.status;
}

console.log("\nConsensus reached! Moving on...\n");

return activityId;
return activity;
}

// Rethrow error
Expand Down
37 changes: 23 additions & 14 deletions examples/with-solana/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import { PublicKey, type Transaction } from "@solana/web3.js";
dotenv.config({ path: path.resolve(process.cwd(), ".env.local") });

import {
getSignatureFromActivity,
TurnkeyActivityConsensusNeededError,
TERMINAL_ACTIVITY_STATUSES,
type TActivity,
} from "@turnkey/http";
import { Turnkey } from "@turnkey/sdk-server";
import { TurnkeySigner } from "@turnkey/solana";
Expand Down Expand Up @@ -94,11 +96,13 @@ async function main() {
});
} catch (error: any) {
signature = await handleActivityError(error).then(
async (activityId: string) => {
const rawSignature = await turnkeySigner.getSignatureFromActivity(
activityId
);
return Buffer.from(rawSignature, "hex");
(activity?: TActivity) => {
if (!activity) {
throw error;
}

const { r, s } = getSignatureFromActivity(activity);
return Buffer.from(`${r}${s}`, "hex");
}
);
}
Expand Down Expand Up @@ -152,13 +156,15 @@ async function main() {
try {
await turnkeySigner.addSignature(transaction, solAddress);
} catch (error: any) {
await handleActivityError(error).then(async (activityId: string) => {
const rawSignature = await turnkeySigner.getSignatureFromActivity(
activityId
);
await handleActivityError(error).then((activity?: TActivity) => {
if (!activity) {
throw error;
}

const { r, s } = getSignatureFromActivity(activity);
transaction.addSignature(
new PublicKey(solAddress),
Buffer.from(rawSignature, "hex")
Buffer.from(`${r}${s}`, "hex")
);
});
}
Expand All @@ -178,6 +184,7 @@ async function main() {
if (error instanceof TurnkeyActivityConsensusNeededError) {
const activityId = error["activityId"]!;
let activityStatus = error["activityStatus"]!;
let activity: TActivity | undefined;

while (!TERMINAL_ACTIVITY_STATUSES.includes(activityStatus)) {
console.log("\nWaiting for consensus...\n");
Expand All @@ -191,18 +198,20 @@ async function main() {
continue;
}

// Refresh activity status
activityStatus = (
// Refresh activity
activity = (
await turnkeyClient.apiClient().getActivity({
activityId,
organizationId: process.env.ORGANIZATION_ID!,
})
).activity.status;
).activity;

activityStatus = activity.status;
}

console.log("\nConsensus reached! Moving on...\n");

return activityId;
return activity;
}

// Rethrow error
Expand Down
44 changes: 24 additions & 20 deletions examples/with-viem/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import {
} from "viem";
import { sepolia } from "viem/chains";

import { TERMINAL_ACTIVITY_STATUSES } from "@turnkey/http";
import {
createAccount,
TERMINAL_ACTIVITY_STATUSES,
getSignatureFromActivity,
getSignedTransactionFromActivity,
type TActivity,
} from "@turnkey/http";
import {
createAccount,
isTurnkeyActivityConsensusNeededError,
serializeSignature,
} from "@turnkey/viem";
Expand Down Expand Up @@ -80,13 +83,12 @@ async function main() {
});
} catch (error: any) {
signature = await handleActivityError(error).then(
async (activityId: string) => {
const rawSignature = await getSignatureFromActivity(
turnkeyClient.apiClient(),
process.env.ORGANIZATION_ID!,
activityId
);
return serializeSignature(rawSignature);
async (activity?: TActivity) => {
if (!activity) {
throw error;
}

return serializeSignature(getSignatureFromActivity(activity));
}
);
}
Expand Down Expand Up @@ -126,15 +128,15 @@ async function main() {
txHash = await client.sendTransaction(transactionRequest);
} catch (error: any) {
txHash = await handleActivityError(error).then(
async (activityId: string) => {
console.log({ activityId });
const signedTx = await getSignedTransactionFromActivity(
turnkeyClient.apiClient(),
process.env.ORGANIZATION_ID!,
activityId
);
async (activity?: TActivity) => {
if (!activity) {
throw error;
}

return await client.sendRawTransaction({
serializedTransaction: signedTx,
serializedTransaction: getSignedTransactionFromActivity(
activity
) as `0x${string}`,
});
}
);
Expand All @@ -149,6 +151,7 @@ async function main() {
const activityId = error["activityId"] || error["cause"]["activityId"];
let activityStatus =
error["activityStatus"] || error["cause"]["activityId"];
let activity: TActivity | undefined;

while (!TERMINAL_ACTIVITY_STATUSES.includes(activityStatus)) {
console.log("\nWaiting for consensus...\n");
Expand All @@ -167,17 +170,18 @@ async function main() {
}

// Refresh activity status
activityStatus = (
activity = (
await turnkeyClient.apiClient().getActivity({
activityId,
organizationId: process.env.ORGANIZATION_ID!,
})
).activity.status;
).activity;
activityStatus = activity.status;
}

console.log("\nConsensus reached! Moving on...\n");

return activityId;
return activity;
}

// Rethrow error
Expand Down
Loading

0 comments on commit ccc9a93

Please sign in to comment.