Skip to content

Commit ec95258

Browse files
authored
Merge pull request #47 from Bako-Labs/p2/feat/coder-utils
FEAT: adds utils to encoding operations
2 parents 185a291 + daa16eb commit ec95258

File tree

13 files changed

+340
-288
lines changed

13 files changed

+340
-288
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'bakosafe': minor
3+
---
4+
5+
feat(coders): add comprehensive encoding utilities and vault signature support

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
.turbo
88
.local/
99
local/
10-
packages/sway/.fuels
10+
packages/sway/.fuels
11+
.context

packages/sdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bakosafe",
3-
"version": "0.3.0",
3+
"version": "0.4.0",
44
"author": "Bako Labs",
55
"description": "A signature validation package built based on sway in the fuel network",
66
"main": "dist/index.js",
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { EncodingService, SignatureService } from './services';
2+
import type { SigLoose } from './services';
3+
import { DEFAULT_PREDICATE_VERSION } from '../../sway/predicates/predicateFinder';
4+
5+
/**
6+
* Centralized class for common encoding operations, such as signature serialization and transaction ID encoding.
7+
*
8+
* @example
9+
* ```ts
10+
* // Encode a wallet signature
11+
* const encodedSignature = CoderUtils.encodeSignature(wallet.address, signature);
12+
*
13+
* // Encode a transaction ID
14+
* const encodedTxId = CoderUtils.encodeTxId(txId, 'v1');
15+
* ```
16+
*/
17+
export class CoderUtils {
18+
/**
19+
* Encodes a signature for use with Bako predicates based on wallet type and predicate version.
20+
*
21+
* @param walletAddress - The wallet address associated with the signature.
22+
* @param signature - The raw or structured signature data.
23+
* @param predicateVersion - (Optional) Predicate version used for encoding.
24+
* Defaults to {@link DEFAULT_PREDICATE_VERSION}.
25+
* @returns The encoded signature as a string.
26+
*/
27+
static encodeSignature(
28+
walletAddress: string,
29+
signature: SigLoose,
30+
predicateVersion: string = DEFAULT_PREDICATE_VERSION,
31+
): string {
32+
return SignatureService.encode(walletAddress, signature, predicateVersion);
33+
}
34+
35+
/**
36+
* Encodes a transaction ID based on the predicate version requirements.
37+
*
38+
* @param txId - The transaction ID to encode.
39+
* @param version - The version identifier for encoding.
40+
* @returns The encoded transaction ID as a `Uint8Array` or `string`,
41+
* depending on the encoding strategy.
42+
*/
43+
static encodeTxId(txId: string, version: string): Uint8Array | string {
44+
return EncodingService.encodeTxId(txId, version);
45+
}
46+
}

packages/sdk/src/modules/coders/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ coders/
99
├── Coder.ts # Main encoding class
1010
├── types.ts # Type definitions
1111
├── factory/ # Factory pattern implementations
12-
│ ├── CoderFactory.ts # Creates configured instances
12+
│ ├── CoderFactory.ts # Creates configured instances (internal)
1313
│ └── index.ts
1414
├── services/ # Encoding services
15-
│ ├── SignatureService.ts # Signature encoding logic
16-
│ ├── EncodingService.ts # Transaction ID encoding
15+
│ ├── SignatureService.ts # Signature encoding logic
16+
│ ├── EncodingService.ts # Transaction ID encoding
1717
│ └── index.ts
18+
├── CoderUtils.ts # Centralizes common encoding operations
1819
├── index.ts # Main exports
1920
└── README.md # This file
2021
```

packages/sdk/src/modules/coders/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717

1818
export * from './coder';
1919
export * from './types';
20-
export * from './factory';
2120
export * from './services';
21+
export { CoderUtils } from './CoderUtils';
2222

2323
// Backward compatibility - deprecated exports
2424
import { CoderFactory } from './factory';
2525
import { SignatureService, EncodingService } from './services';
2626

2727
/**
28-
* @deprecated Use CoderFactory.createFullCoder() instead
28+
* @deprecated Use CoderUtils.encodeSignature() instead
2929
*
3030
* This export is maintained for backward compatibility but should not
3131
* be used in new code. Use the factory pattern instead for better
@@ -34,7 +34,7 @@ import { SignatureService, EncodingService } from './services';
3434
export const bakoCoder = CoderFactory.createFullCoder();
3535

3636
/**
37-
* @deprecated Use SignatureService.encode() instead
37+
* @deprecated Use CoderUtils.encodeSignature() instead
3838
*
3939
* This export is maintained for backward compatibility but should not
4040
* be used in new code. Use the SignatureService class directly for
@@ -43,7 +43,7 @@ export const bakoCoder = CoderFactory.createFullCoder();
4343
export const encodeSignature = SignatureService.encode;
4444

4545
/**
46-
* @deprecated Use EncodingService.encodeTxId() instead
46+
* @deprecated Use CoderUtils.encodeTxId() instead
4747
*
4848
* This export is maintained for backward compatibility but should not
4949
* be used in new code. Use the EncodingService class directly for

packages/sdk/src/modules/coders/services/EncodingService.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,18 @@
11
import { arrayify } from 'fuels';
22
import { stringToHex } from 'viem';
33
import { BYTE_VERSION_LIST, BytesVersion } from '../types';
4-
import { getTxIdEncoded } from '..';
54
import { ENCODING_VERSIONS } from '../utils/versionsByEncode';
65

76
/**
87
* Service class for encoding operations related to transaction IDs and general encoding tasks.
98
*/
109
export class EncodingService {
11-
/**
12-
* Set of predicate versions for efficient lookup of byte-encoding requirements.
13-
*/
14-
private static readonly BYTE_VERSION_SET = new Set<string>(
15-
BYTE_VERSION_LIST as readonly string[],
16-
);
17-
18-
1910
/**
2011
* Encodes a transaction ID based on the predicate version requirements.
2112
*/
2213
static encodeTxId(txId: string, version: string): Uint8Array | string {
2314
switch (true) {
24-
case EncodingService.BYTE_VERSION_SET.has(version):
15+
case this.requiresByteEncoding(version):
2516
return arrayify(txId.startsWith('0x') ? txId : `0x${txId}`);
2617
default:
2718
return txId.startsWith('0x')
@@ -33,8 +24,8 @@ export class EncodingService {
3324
/**
3425
* Encodes a transaction ID for BakoSafe predicates
3526
*/
36-
static bakosafeEncode = (txId: string, version: string) => {
37-
return this.encodeTxId(txId, version) as string;
27+
static bakosafeEncode = (txId: string) => {
28+
return txId.startsWith('0x') ? txId.slice(2) : txId;
3829
};
3930

4031
/**
@@ -45,15 +36,15 @@ export class EncodingService {
4536
};
4637

4738
/**
48-
* Determines the encoding function for a given version
49-
*/
39+
* Determines the encoding function for a given version
40+
*/
5041
static determineEncodingFunction(version: string): (txId: string) => string {
5142
if (ENCODING_VERSIONS.with0xPrefix.includes(version)) {
5243
return this.connectorEncode;
5344
}
5445

5546
if (ENCODING_VERSIONS.without0xPrefix.includes(version)) {
56-
return (txId: string) => this.bakosafeEncode(txId, version);
47+
return (txId: string) => this.bakosafeEncode(txId);
5748
}
5849

5950
throw new Error(`Unsupported version: ${version}`);
@@ -71,7 +62,7 @@ export class EncodingService {
7162
* Checks if a predicate version requires byte array encoding.
7263
*/
7364
static requiresByteEncoding(version: string): version is BytesVersion {
74-
return EncodingService.BYTE_VERSION_SET.has(version);
65+
return ENCODING_VERSIONS.with0xPrefix.includes(version);
7566
}
7667

7768
/**
@@ -80,4 +71,4 @@ export class EncodingService {
8071
static getByteVersions(): readonly string[] {
8172
return BYTE_VERSION_LIST;
8273
}
83-
}
74+
}

packages/sdk/src/modules/coders/services/SignatureService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { CoderFactory } from '../factory';
1717
/**
1818
* Flexible signature type that accepts BytesLike data, signature objects, or WebAuthn inputs.
1919
*/
20-
type SigLoose = BytesLike | { signature: BytesLike } | WebAuthnInput;
20+
export type SigLoose = BytesLike | { signature: BytesLike } | WebAuthnInput;
2121

2222
/**
2323
* Classification result for different signature types with their corresponding data.

packages/sdk/src/modules/vault/Vault.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
} from './services';
3838
import { VaultConfigurationFactory } from './factory';
3939
import { Asset } from './assets';
40-
import { EncodingService } from '../coders';
40+
import { EncodingService, SignatureService, type SigLoose } from '../coders';
4141

4242
import partition from 'lodash.partition';
4343

@@ -303,6 +303,17 @@ export class Vault extends Predicate<[]> {
303303
throw new Error('Use a VaultProvider to consume this method');
304304
}
305305

306+
/**
307+
* Encodes a signature according to the vault version.
308+
*
309+
* @param walletAddress - Address of the signer who produced the signature.
310+
* @param signature - The raw or structured signature.
311+
* @returns Encoded signature string compatible with the vault version.
312+
*/
313+
public encodeSignature(walletAddress: string, signature: SigLoose) {
314+
return SignatureService.encode(walletAddress, signature, this.version);
315+
}
316+
306317
/**
307318
* Recovers a `Vault` instance from a predicate address.
308319
*
@@ -387,6 +398,7 @@ export class Vault extends Predicate<[]> {
387398
async transaction(params: VaultTransaction): Promise<{
388399
tx: TransactionRequest;
389400
hashTxId: string;
401+
encodedTxId: string;
390402
}> {
391403
const { assets } = params;
392404
const assetsWithAddressType = await Promise.all(

0 commit comments

Comments
 (0)