Skip to content
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
1 change: 1 addition & 0 deletions modules/sdk-coin-tempo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
},
"dependencies": {
"@bitgo/abstract-eth": "^24.22.0",
"@bitgo/sdk-lib-mpc": "^10.10.0",
"@bitgo/sdk-core": "^36.37.0",
"@bitgo/secp256k1": "^1.11.0",
"@bitgo/statics": "^58.32.0",
Expand Down
11 changes: 11 additions & 0 deletions modules/sdk-coin-tempo/src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,14 @@ export const TIP20_DECIMALS = 6;
* Tempo uses EIP-7702 Account Abstraction with transaction type 0x76
*/
export const AA_TRANSACTION_TYPE = '0x76' as const;

/**
* Fallback JSON-RPC endpoints when `common.Environments[bitgo.getEnv()].evm.tempo|ttempo.rpcUrl`
* is missing (should not happen for normal envs). Primary RPC config lives in sdk-core
* `environments.ts` under `evm.tempo` / `evm.ttempo`; `@bitgo/statics` networks only define
* explorer URLs and chainId, not RPC.
*/
export const TEMPO_RPC_URLS = {
MAINNET: 'https://rpc.mainnet.tempo.xyz',
TESTNET: 'https://rpc.testnet.tempo.xyz',
} as const;
12 changes: 12 additions & 0 deletions modules/sdk-coin-tempo/src/lib/iface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
/**
* Interfaces for Tempo
*/
import type { RecoverOptions } from '@bitgo/abstract-eth';

/**
* Optional Tempo-specific recovery fields (passed on {@link RecoverOptions}).
* Fees on Tempo are paid in a TIP-20 token; defaults to the recovered token.
*/
export type TempoRecoveryOptions = RecoverOptions & {
/** TIP-20 contract used to pay AA gas (defaults to token being swept) */
feeTokenAddress?: string;
/** Override default public RPC URL */
rpcUrl?: string;
};

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface TransactionData {
Expand Down
38 changes: 36 additions & 2 deletions modules/sdk-coin-tempo/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

import { bip32 } from '@bitgo/secp256k1';
import { ethers } from 'ethers';
import { AA_TRANSACTION_TYPE, TIP20_DECIMALS } from './constants';
import { TIP20_TRANSFER_WITH_MEMO_ABI } from './tip20Abi';
import { AA_TRANSACTION_TYPE, TEMPO_RPC_URLS, TIP20_DECIMALS } from './constants';
import { TIP20_ABI, TIP20_TRANSFER_WITH_MEMO_ABI } from './tip20Abi';

const AA_TX_HEX_REGEX = new RegExp(`^${AA_TRANSACTION_TYPE}[0-9a-f]*$`, 'i');

Expand Down Expand Up @@ -149,6 +149,37 @@ export function isValidMemoId(memoId: string): boolean {
return typeof memoId === 'string' && /^(0|[1-9]\d*)$/.test(memoId);
}

/**
* Resolve default Tempo JSON-RPC URL from base chain name.
*/
export function getTempoRpcUrlForBaseChain(baseChain: string): string {
return baseChain === 'ttempo' ? TEMPO_RPC_URLS.TESTNET : TEMPO_RPC_URLS.MAINNET;
}

/**
* Query TIP-20 balance via standard `balanceOf` eth_call.
*/
export async function queryTip20TokenBalance(
rpcUrl: string,
tokenContractAddress: string,
walletAddress: string
): Promise<bigint> {
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
const iface = new ethers.utils.Interface(TIP20_ABI);
const data = iface.encodeFunctionData('balanceOf', [walletAddress]);
const result = await provider.call({ to: ethers.utils.getAddress(tokenContractAddress), data });
const [bal] = iface.decodeFunctionResult('balanceOf', result);
return BigInt(bal.toString());
}

/**
* Pending nonce for an address (for AA / account tx ordering).
*/
export async function getTempoAddressNonce(rpcUrl: string, address: string): Promise<number> {
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
return provider.getTransactionCount(ethers.utils.getAddress(address), 'pending');
}

const utils = {
isValidAddress,
isValidPublicKey,
Expand All @@ -160,6 +191,9 @@ const utils = {
isValidTip20Amount,
isTip20Transaction,
isValidMemoId,
getTempoRpcUrlForBaseChain,
queryTip20TokenBalance,
getTempoAddressNonce,
};

export default utils;
Loading
Loading