Skip to content

Commit e4fe395

Browse files
committed
feat(sdk-coin-tempo): add tip20 skeleton
TICKET: WIN-8480
1 parent 14f4801 commit e4fe395

File tree

12 files changed

+377
-171
lines changed

12 files changed

+377
-171
lines changed

modules/sdk-coin-tempo/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
]
4141
},
4242
"dependencies": {
43+
"@bitgo/abstract-eth": "^24.19.4",
4344
"@bitgo/sdk-core": "^36.25.0",
45+
"@bitgo/secp256k1": "^1.8.0",
4446
"@bitgo/statics": "^58.19.0"
4547
},
4648
"devDependencies": {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from './lib';
22
export * from './tempo';
33
export * from './ttempo';
4+
export * from './tip20Token';
45
export * from './register';

modules/sdk-coin-tempo/src/lib/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Constants for Tempo
2+
* Constants for Tempo blockchain (EVM-compatible)
33
*/
44

55
export const MAINNET_COIN = 'tempo';

modules/sdk-coin-tempo/src/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from './keyPair';
22
export * from './utils';
33
export * from './constants';
44
export * from './iface';
5+
export * from './tip20Abi';
Lines changed: 19 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,37 @@
1-
import { DefaultKeys, isPrivateKey, isPublicKey, isSeed, KeyPairOptions } from '@bitgo/sdk-core';
2-
import * as crypto from 'crypto';
1+
/**
2+
* Tempo KeyPair - Reuses Ethereum KeyPair Implementation
3+
*
4+
* Since Tempo is EVM-compatible and uses the same cryptography (ECDSA/secp256k1)
5+
* as Ethereum, we can directly reuse the Ethereum KeyPair implementation.
6+
*/
7+
8+
import { bip32 } from '@bitgo/secp256k1';
9+
import { DefaultKeys, KeyPairOptions } from '@bitgo/sdk-core';
310

411
/**
5-
* Tempo keys and address management
12+
* Tempo KeyPair class
13+
* Uses same key derivation as Ethereum (BIP32 + secp256k1)
614
*/
715
export class KeyPair {
816
private keyPair: DefaultKeys;
917

10-
/**
11-
* Public constructor. By default, creates a key pair with a random master seed.
12-
*
13-
* @param { KeyPairOptions } source Either a master seed, a private key, or a public key
14-
*/
1518
constructor(source?: KeyPairOptions) {
16-
let seed: Buffer;
17-
18-
if (!source) {
19-
seed = crypto.randomBytes(32);
20-
} else if (isSeed(source)) {
21-
seed = source.seed;
22-
} else if (isPrivateKey(source)) {
23-
// TODO: Implement private key to keypair conversion
24-
throw new Error('Private key import not yet implemented');
25-
} else if (isPublicKey(source)) {
26-
// TODO: Implement public key import
27-
throw new Error('Public key import not yet implemented');
28-
} else {
29-
throw new Error('Invalid key pair options');
30-
}
31-
32-
// TODO: Generate actual keypair from seed based on the coin's key derivation
33-
this.keyPair = this.generateKeyPairFromSeed(seed);
34-
}
35-
36-
/**
37-
* Generate a keypair from a seed
38-
* @param seed
39-
* @private
40-
*/
41-
private generateKeyPairFromSeed(seed: Buffer): DefaultKeys {
42-
// TODO: Implement actual key generation for Tempo
43-
// This is a placeholder implementation
44-
const prv = seed.toString('hex');
45-
const pub = crypto.createHash('sha256').update(seed).digest('hex');
19+
// TODO: Implement proper key generation when needed
20+
const seed = Buffer.alloc(64);
21+
const hdNode = bip32.fromSeed(seed);
4622

47-
return {
48-
prv,
49-
pub,
23+
this.keyPair = {
24+
prv: hdNode.toBase58(),
25+
pub: hdNode.neutered().toBase58(),
5026
};
5127
}
5228

53-
/**
54-
* Get the public key
55-
*/
5629
getKeys(): DefaultKeys {
5730
return this.keyPair;
5831
}
5932

60-
/**
61-
* Get the address
62-
*/
6333
getAddress(): string {
64-
// TODO: Implement address derivation from public key
65-
return this.keyPair.pub;
34+
// TODO: Implement Ethereum-style address derivation
35+
return '0x0000000000000000000000000000000000000000';
6636
}
6737
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* TIP20 Token Standard ABI (Skeleton)
3+
*
4+
* TODO: Update this file when TIP20 ABI becomes available
5+
*/
6+
7+
/**
8+
* Placeholder TIP20 ABI
9+
* This is an empty array that should be replaced with the actual ABI
10+
*/
11+
export const TIP20_ABI = [] as const;
12+
13+
/**
14+
* Placeholder for TIP20 Factory ABI
15+
*/
16+
export const TIP20_FACTORY_ABI = [] as const;
17+
18+
/**
19+
* Get the method signature for TIP20 transfer
20+
* TODO: Update with actual method name if different from ERC20
21+
*/
22+
export function getTip20TransferSignature(): string {
23+
return 'transfer(address,uint256)';
24+
}
25+
26+
/**
27+
* Get the method signature for TIP20 transferFrom
28+
* TODO: Update with actual method name if different from ERC20
29+
*/
30+
export function getTip20TransferFromSignature(): string {
31+
return 'transferFrom(address,address,uint256)';
32+
}

modules/sdk-coin-tempo/src/lib/utils.ts

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,54 @@
1-
import { VALID_ADDRESS_REGEX, VALID_PUBLIC_KEY_REGEX } from './constants';
2-
31
/**
4-
* Utility functions for Tempo
2+
* Tempo Utility Functions
3+
*
4+
* Since Tempo is EVM-compatible, we can reuse Ethereum utilities
5+
56
*/
67

8+
import { bip32 } from '@bitgo/secp256k1';
9+
import { VALID_ADDRESS_REGEX } from './constants';
10+
711
/**
8-
* Check if the address is valid
9-
* @param address
12+
* Check if address is valid Ethereum-style address
13+
* TODO: Replace with ETH utils when implementing
1014
*/
1115
export function isValidAddress(address: string): boolean {
12-
// TODO: Implement proper address validation for Tempo
16+
if (typeof address !== 'string') {
17+
return false;
18+
}
1319
return VALID_ADDRESS_REGEX.test(address);
1420
}
1521

1622
/**
17-
* Check if the public key is valid
18-
* @param publicKey
23+
* Check if public key is valid (BIP32 xpub format)
24+
* TODO: Replace with ETH utils when implementing
1925
*/
2026
export function isValidPublicKey(publicKey: string): boolean {
21-
// TODO: Implement proper public key validation for Tempo
22-
return VALID_PUBLIC_KEY_REGEX.test(publicKey);
27+
if (typeof publicKey !== 'string') {
28+
return false;
29+
}
30+
try {
31+
const hdNode = bip32.fromBase58(publicKey);
32+
return hdNode.isNeutered();
33+
} catch (e) {
34+
return false;
35+
}
2336
}
2437

2538
/**
26-
* Check if the private key is valid
27-
* @param privateKey
39+
* Check if private key is valid (BIP32 xprv format)
40+
* TODO: Replace with ETH utils when implementing
2841
*/
2942
export function isValidPrivateKey(privateKey: string): boolean {
30-
// TODO: Implement proper private key validation for Tempo
31-
return privateKey.length === 64;
43+
if (typeof privateKey !== 'string') {
44+
return false;
45+
}
46+
try {
47+
const hdNode = bip32.fromBase58(privateKey);
48+
return !hdNode.isNeutered();
49+
} catch (e) {
50+
return false;
51+
}
3252
}
3353

3454
const utils = {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,35 @@
11
import { BitGoBase } from '@bitgo/sdk-core';
22
import { Tempo } from './tempo';
33
import { Ttempo } from './ttempo';
4+
import { Tip20Token } from './tip20Token';
45

6+
/**
7+
* Register Tempo and TIP20 tokens with the SDK
8+
* @param sdk - BitGo SDK instance
9+
*/
510
export const register = (sdk: BitGoBase): void => {
11+
// Register base Tempo coins
612
sdk.register('tempo', Tempo.createInstance);
713
sdk.register('ttempo', Ttempo.createInstance);
14+
15+
// Register TIP20 tokens (skeleton)
16+
// TODO: Add actual token configurations from @bitgo/statics
17+
// For now, this creates an empty array which can be populated progressively
18+
const tip20Tokens = Tip20Token.createTokenConstructors([
19+
// TODO: Add TIP20 token configurations here
20+
// Example:
21+
// {
22+
// type: 'tempo:usdc',
23+
// coin: 'tempo',
24+
// network: 'Mainnet',
25+
// name: 'USD Coin on Tempo',
26+
// tokenContractAddress: '0x...',
27+
// decimalPlaces: 6,
28+
// },
29+
]);
30+
31+
// Register each TIP20 token with the SDK
32+
tip20Tokens.forEach(({ name, coinConstructor }) => {
33+
sdk.register(name, coinConstructor);
34+
});
835
};

0 commit comments

Comments
 (0)