0.1.4 • Published 8 months ago
@safe-explain/api-kit v0.1.4
Safe Explain SDK
A TypeScript library providing type definitions and utilities for web3 transaction analysis and explanation.
Installation
npm install safe-explain-sdk
# or
yarn add safe-explain-sdkFeatures
- Type Definitions: Comprehensive TypeScript type definitions for transaction analysis
- Styled Steps: Create informative, warning, and critical steps with built-in styling
- Response Utilities: Helper functions for creating standardized API responses
- Contract Parameters: Display contract function parameters in a structured list format
- Batch Creation: Easily create multiple steps from data arrays
Usage
Basic Example
import {
createInfoStep,
createWarningStep,
createCriticalStep,
} from "safe-explain-sdk/transaction/step";
import { TransactionAnalysis } from "safe-explain-sdk/transaction/response";
import { ApiResponseUtils } from "safe-explain-sdk/common/response";
// Create transaction analysis result
const analysis: TransactionAnalysis = {
steps: [
createInfoStep("Transaction Type", "Token Swap"),
createInfoStep("Amount", "0.5 ETH → 1,500 USDC"),
createWarningStep("Gas Fee", "Higher than network average"),
createCriticalStep("Security Risk", "Contract not verified"),
],
};
// Create API response
const response = ApiResponseUtils.success(analysis);Contract Parameters Example
import {
createParametersStep,
ParameterItem,
} from "safe-explain-sdk/transaction/step";
// Contract function parameters
const swapParameters: ParameterItem[] = [
{
name: "tokenIn",
value: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
remarks: "DAI Token Contract",
},
{
name: "tokenOut",
value: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
remarks: "WETH Token Contract",
},
{
name: "amountIn",
value: "1000000000000000000000",
remarks: "1000 DAI (with 18 decimals)",
},
{
name: "minAmountOut",
value: "450000000000000000",
remarks: "Minimum 0.45 WETH expected",
},
{
name: "deadline",
value: "1698557954",
remarks: "Transaction deadline timestamp",
},
];
// Create a step with parameter list
const parametersStep = createParametersStep(
"Contract Function Parameters",
"swap(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, uint256 deadline)",
swapParameters
);Batch Creating Steps
The createSteps function allows you to create multiple steps at once from an array of data:
import { createSteps, StepType } from "safe-explain-sdk/transaction/step";
// Step data array - could come from an API response or config
const stepsData = [
{
type: "info" as StepType,
title: "Transaction Type",
content: "Token Transfer",
},
{
type: "warning" as StepType,
title: "Network Fee",
content: "Gas price is high",
},
{
type: "parameters" as StepType,
title: "Function Parameters",
content: "transfer(address to, uint256 amount)",
parameters: [
{ name: "to", value: "0x123...abc", remarks: "Recipient address" },
{ name: "amount", value: "1000000000000000000", remarks: "1 Token" },
],
},
];
// Create all steps at once
const steps = createSteps(stepsData);Displaying in React
import React from "react";
import {
Step,
isParametersStep,
ParameterItem,
} from "safe-explain-sdk/transaction/step";
// Component to display a single parameter
const ParameterItemComponent: React.FC<{ param: ParameterItem }> = ({
param,
}) => {
return (
<div
style={{
display: "flex",
padding: "8px 12px",
borderBottom: "1px solid #f0f0f0",
}}
>
<div style={{ flex: "0 0 150px", fontWeight: "bold" }}>{param.name}:</div>
<div style={{ flex: "1 0 auto" }}>
<div>{param.value}</div>
{param.remarks && (
<div style={{ fontSize: "0.85em", opacity: 0.8 }}>
{param.remarks}
</div>
)}
</div>
</div>
);
};
// Enhanced StepComponent to handle parameters
const StepComponent: React.FC<{ step: Step }> = ({ step }) => {
// Determine styling based on step type
let style = {};
let icon = "";
if (isInfoStep(step)) {
style = { color: "#1890FF", backgroundColor: "#E6F7FF" };
icon = "ℹ️";
} else if (isWarningStep(step)) {
style = { color: "#FAAD14", backgroundColor: "#FFFBE6" };
icon = "⚠️";
} else if (isCriticalStep(step)) {
style = { color: "#FF4D4F", backgroundColor: "#FFF1F0" };
icon = "🛑";
} else if (isParametersStep(step)) {
style = { color: "#722ED1", backgroundColor: "#F9F0FF" };
icon = "📝";
}
// Render parameters list if this is a parameters step
const renderContent = () => {
if (isParametersStep(step)) {
return (
<div style={{ margin: "10px 0" }}>
<div style={{ marginBottom: "8px" }}>{step.content}</div>
<div
style={{
border: "1px solid #eaeaea",
borderRadius: "4px",
overflow: "hidden",
}}
>
{step.parameters.map((param, idx) => (
<ParameterItemComponent key={idx} param={param} />
))}
</div>
</div>
);
}
// Regular content for other step types
return <p>{step.content}</p>;
};
return (
<div
style={{
...style,
padding: "12px",
borderRadius: "6px",
marginBottom: "12px",
}}
>
<h3>
{icon} {step.title}
</h3>
{renderContent()}
</div>
);
};
// Component to display all steps
const StepsList: React.FC<{ steps: Step[] }> = ({ steps }) => {
return (
<div>
{steps.map((step, index) => (
<StepComponent key={index} step={step} />
))}
</div>
);
};Advanced Usage
Dynamic Analysis Generation
You can dynamically generate analysis based on transaction data:
function analyzeTransaction(txData: any): TransactionAnalysis {
const steps = [];
// Add basic info
steps.push({
type: "info" as StepType,
title: "Transaction Type",
content: txData.isContractCall ? "Contract Interaction" : "ETH Transfer",
});
// Add amount info
if (txData.value && txData.value !== "0") {
steps.push({
type: "info" as StepType,
title: "Value",
content: `${txData.valueFormatted} ETH`,
});
}
// Add contract parameters if present
if (txData.methodName && txData.params) {
steps.push({
type: "parameters" as StepType,
title: "Contract Call",
content: txData.methodName,
parameters: txData.params.map((p: any) => ({
name: p.name,
value: p.value,
remarks: p.description,
})),
});
}
// Add warnings based on analysis
if (txData.isNewContract) {
steps.push({
type: "warning" as StepType,
title: "New Contract",
content: "You are interacting with a recently deployed contract",
});
}
// Add critical warnings for high-risk interactions
if (txData.riskScore > 80) {
steps.push({
type: "critical" as StepType,
title: "High Risk Detected",
content: txData.riskDetails,
});
}
return {
steps: createSteps(steps),
};
}API Reference
Step Types
Four step types are available to represent different information types:
InfoStep: General information about the transactionWarningStep: Warnings that require user attentionCriticalStep: Critical issues that may indicate serious risksParametersStep: Contract function parameters displayed as a structured list
Factory Functions
// Create info step
createInfoStep(title: string, content: string): InfoStep;
// Create warning step
createWarningStep(title: string, content: string): WarningStep;
// Create critical step
createCriticalStep(title: string, content: string): CriticalStep;
// Create parameters step
createParametersStep(
title: string,
content: string,
parameters: ParameterItem[]
): ParametersStep;
// Create multiple steps at once
createSteps(
steps: Array<{
type: StepType;
title: string;
content: string;
parameters?: ParameterItem[];
}>
): Step[];Response Utilities
// Create success response
ApiResponseUtils.success<T>(data: T): ApiResponse<T>;
// Create error response
ApiResponseUtils.error<T>(message: string): ApiResponse<T>;TypeScript Types
Step Interfaces
// Step types
type StepType = "info" | "warning" | "critical" | "parameters";
// Base step structure
interface BaseStep {
title: string; // Step title
content: string; // Step content/description
type: StepType; // Step type
remarks?: string; // Optional remarks
}
// Specific step types
interface InfoStep extends BaseStep {
type: "info";
}
interface WarningStep extends BaseStep {
type: "warning";
}
interface CriticalStep extends BaseStep {
type: "critical";
}
// Parameter item for contract parameters
interface ParameterItem {
name: string; // Parameter name
value: string; // Parameter value
remarks?: string; // Optional remarks about the parameter
}
// Parameters step with list of parameters
interface ParametersStep extends BaseStep {
type: "parameters";
parameters: ParameterItem[];
}
// Union type for all step types
type Step = InfoStep | WarningStep | CriticalStep | ParametersStep;Response Types
interface ApiResponse<T> {
success: boolean; // Indicates if the request was successful
data: T; // Response data
error?: string; // Optional error message
}
interface TransactionAnalysis {
steps: Step[]; // Analysis steps for UI display
}License
MIT