Skip to content
Open
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
160 changes: 151 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,8 @@
"sinon": "21.0.1",
"typescript": "5.9.3",
"vitest": "3.2.4"
},
"dependencies": {
"uint8arrays": "^5.1.0"
}
}
9 changes: 7 additions & 2 deletions packages/utils/src/cacao.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { AuthTypes } from "@walletconnect/types";
import { getCommonValuesInArrays } from "./misc.js";
import { verifySignature } from "./signatures.js";
import { fromString, toString } from "uint8arrays";

const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();

const didPrefix = "did:pkh:";
const NAMESPACE_DISPLAY_NAMES = {
eip155: "Ethereum",
Expand Down Expand Up @@ -225,11 +230,11 @@ export function getReCapActions(abilities: any[]) {
}

export function base64Encode(input: unknown): string {
return Buffer.from(JSON.stringify(input)).toString("base64");
return toString(textEncoder.encode(JSON.stringify(input)), "base64");
}

export function base64Decode(encodedString: string): string {
return JSON.parse(Buffer.from(encodedString, "base64").toString("utf-8"));
return JSON.parse(textDecoder.decode(fromString(encodedString, "base64")));
}

export function isValidRecap(recap: any) {
Expand Down
11 changes: 7 additions & 4 deletions packages/utils/src/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ export function isTypeTwoEnvelope(
}

export function getCryptoKeyFromKeyData(keyData: P256KeyDataType): Uint8Array {
const xBuffer = Buffer.from(keyData.x, "base64");
const yBuffer = Buffer.from(keyData.y, "base64");
const xBuffer = fromString(fromBase64URL(keyData.x), BASE64);
const yBuffer = fromString(fromBase64URL(keyData.y), BASE64);

// Concatenate x and y coordinates with 0x04 prefix (uncompressed point format)
return concat([new Uint8Array([0x04]), xBuffer, yBuffer]);
Expand All @@ -235,7 +235,10 @@ export function verifyP256Jwt<T>(token: string, keyData: P256KeyDataType) {
const [headerBase64Url, payloadBase64Url, signatureBase64Url] = token.split(".");

// Decode the signature
const signatureBuffer = Buffer.from(fromBase64URL(signatureBase64Url), "base64");
const signatureBuffer = fromString(
fromBase64URL(signatureBase64Url),
BASE64
);

// Check if signature length is correct (64 bytes for P-256)
if (signatureBuffer.length !== 64) {
Expand All @@ -250,7 +253,7 @@ export function verifyP256Jwt<T>(token: string, keyData: P256KeyDataType) {
const signingInput = `${headerBase64Url}.${payloadBase64Url}`;

// Hash the signing input
const messageHash = sha256(signingInput);
const messageHash = sha256(fromString(signingInput, UTF8));

// Get the public key in uncompressed point format
const publicKey = getCryptoKeyFromKeyData(keyData);
Expand Down
5 changes: 3 additions & 2 deletions packages/utils/src/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getDocument, getLocation, getNavigator } from "@walletconnect/window-ge
import { getWindowMetadata } from "@walletconnect/window-metadata";
import { ErrorResponse } from "@walletconnect/jsonrpc-utils";
import { IKeyValueStorage } from "@walletconnect/keyvaluestorage";
import { fromString, toString } from "uint8arrays";

import { getInternalError, SDKError } from "./errors.js";

Expand Down Expand Up @@ -551,12 +552,12 @@ export function isIframe() {
}

export function toBase64(input: string, removePadding = false): string {
const encoded = Buffer.from(input).toString("base64");
const encoded = toString(new TextEncoder().encode(input), "base64");
return removePadding ? encoded.replace(/[=]/g, "") : encoded;
}

export function fromBase64(encodedString: string): string {
return Buffer.from(encodedString, "base64").toString("utf-8");
return new TextDecoder().decode(fromString(encodedString, "base64"));
}

export function sleep(ms: number) {
Expand Down
16 changes: 9 additions & 7 deletions packages/utils/src/polkadot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { base58 } from "@scure/base";
import { blake2b } from "blakejs";
import { fromString, toString } from "uint8arrays";

export function ss58AddressToPublicKey(address: string): Uint8Array {
const decoded = base58.decode(address);
Expand Down Expand Up @@ -32,7 +33,7 @@ export function addSignatureToExtrinsic({
const tipBytes = compactEncodeBigInt(tip);

const body = new Uint8Array([
0x00, // MultiAddress::Id
0x00,
...publicKey,
signatureType,
...signature,
Expand All @@ -49,7 +50,7 @@ export function addSignatureToExtrinsic({
export function deriveExtrinsicHash(signedExtrinsicHex: string): string {
const bytes = hexToBytes(signedExtrinsicHex);
const hash = blake2b(bytes, undefined, 32);
return "0x" + Buffer.from(hash).toString("hex");
return "0x" + toString(hash, "hex");
}

function hexToBytes(hex: string): Uint8Array {
Expand All @@ -68,9 +69,9 @@ function normalizeHex(input: string): string {
function guessSignatureTypeFromAddress(address: string): number {
const decoded = base58.decode(address);
const prefix = decoded[0];
if (prefix === 42) return 0x00; // Ed25519
if (prefix === 60) return 0x02; // Secp256k1
return 0x01; // Default Sr25519
if (prefix === 42) return 0x00;
if (prefix === 60) return 0x02;
return 0x01;
}

function compactEncodeInt(value: number): Uint8Array {
Expand Down Expand Up @@ -118,11 +119,12 @@ export function buildSignedExtrinsicHash(payload: {
};
signature: string;
}) {
const signature = Uint8Array.from(Buffer.from(payload.signature, "hex"));
const signature = fromString(payload.signature, "hex");

const publicKey = ss58AddressToPublicKey(payload.transaction.address);
const signed = addSignatureToExtrinsic({ publicKey, signature, payload: payload.transaction });
const hexSigned = Buffer.from(signed).toString("hex");

const hexSigned = toString(signed, "hex");
const hash = deriveExtrinsicHash(hexSigned);

return hash;
Expand Down
Loading
Loading