Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@0xsequence/core

Package Overview
Dependencies
Maintainers
5
Versions
301
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@0xsequence/core - npm Package Compare versions

Comparing version 0.0.0-20230621220927 to 0.0.0-20230622143614

1

dist/declarations/src/commons/signature.d.ts

@@ -25,2 +25,3 @@ import { ethers } from 'ethers';

encode: (data: T | Z | ethers.BytesLike) => string;
trim: (data: string) => Promise<string>;
recover: (data: Z, payload: SignedPayload, provider: ethers.providers.Provider) => Promise<T>;

@@ -27,0 +28,0 @@ supportsNoChainId: boolean;

@@ -34,2 +34,5 @@ import { ethers } from "ethers";

export declare function isTopology(topology: any): topology is Topology;
export declare function encodeSignerLeaf(leaf: SignerLeaf): string;
export declare function decodeSignerLeaf(encoded: string): SignerLeaf;
export declare function isEncodedSignerLeaf(encoded: string): boolean;
export declare function hashNode(node: Node | Leaf): string;

@@ -36,0 +39,0 @@ export declare function leftFace(topology: Topology): Topology[];

@@ -108,2 +108,8 @@ import { BigNumberish, ethers } from "ethers";

export declare function signaturesOfDecoded(utopology: UnrecoveredTopology): string[];
export declare function subdigestsOfDecoded(utopology: UnrecoveredTopology): string[];
export declare function trimSignature(signature: string | UnrecoveredSignature): Promise<string>;
export declare function trimUnrecoveredTree(tree: UnrecoveredTopology, trimStaticDigest?: boolean): Promise<{
weight: number;
trimmed: UnrecoveredTopology;
}>;
export declare const SignatureCoder: base.SignatureCoder<WalletConfig, Signature, UnrecoveredChainedSignature | UnrecoveredSignature>;

4

package.json
{
"name": "@0xsequence/core",
"version": "0.0.0-20230621220927",
"version": "0.0.0-20230622143614",
"description": "core primitives for interacting with the sequence wallet contracts",

@@ -23,3 +23,3 @@ "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/core",

"dependencies": {
"@0xsequence/abi": "0.0.0-20230621220927"
"@0xsequence/abi": "0.0.0-20230622143614"
},

@@ -26,0 +26,0 @@ "scripts": {

@@ -36,2 +36,4 @@

trim: (data: string) => Promise<string>,
recover: (

@@ -38,0 +40,0 @@ data: Z,

@@ -229,2 +229,6 @@

trim: async (data: string): Promise<string> => {
return data
},
supportsNoChainId: true,

@@ -231,0 +235,0 @@

@@ -44,3 +44,3 @@

export function isSubdigestLeaf(leaf: any): leaf is SubdigestLeaf {
return (leaf as SubdigestLeaf).subdigest !== undefined
return (leaf as SubdigestLeaf).subdigest !== undefined && (leaf as SignerLeaf).address === undefined
}

@@ -140,8 +140,36 @@

export function encodeSignerLeaf(leaf: SignerLeaf): string {
return ethers.utils.solidityPack(
['uint96', 'address'],
[leaf.weight, leaf.address]
)
}
export function decodeSignerLeaf(encoded: string): SignerLeaf {
const bytes = ethers.utils.arrayify(encoded);
if (bytes.length !== 32) {
throw new Error('Invalid encoded string length');
}
const weight = ethers.BigNumber.from(bytes.slice(0, 12));
const address = ethers.utils.getAddress(ethers.utils.hexlify(bytes.slice(12)));
return { weight, address }
}
export function isEncodedSignerLeaf(encoded: string): boolean {
const bytes = ethers.utils.arrayify(encoded)
if (bytes.length !== 32) {
return false
}
const prefix = bytes.slice(0, 11)
return prefix.every((byte) => byte === 0)
}
export function hashNode(node: Node | Leaf): string {
if (isSignerLeaf(node)) {
return ethers.utils.solidityPack(
['uint96', 'address'],
[node.weight, node.address]
)
return encodeSignerLeaf(node)
}

@@ -148,0 +176,0 @@

import { BigNumberish, ethers } from "ethers"
import { isValidSignature, recoverSigner, tryRecoverSigner } from "../commons/signer"
import { hashNode, isNestedLeaf, isNode, isNodeLeaf, isSignerLeaf, isSubdigestLeaf, Leaf, WalletConfig, SignerLeaf, Topology, imageHash } from "./config"
import { hashNode, isNestedLeaf, isNode, isNodeLeaf, isSignerLeaf, isSubdigestLeaf, Leaf, WalletConfig, SignerLeaf, Topology, imageHash, NodeLeaf, decodeSignerLeaf, isEncodedSignerLeaf } from "./config"
import * as base from '../commons/signature'

@@ -335,3 +335,3 @@ import { hashSetImageHash } from "./chained"

if (config.threshold > 255) {
if (ethers.BigNumber.from(config.threshold).gt(255)) {
return {

@@ -370,3 +370,6 @@ encoded: ethers.utils.solidityPack(

if (trim && left.weight.eq(0) && right.weight.eq(0)) {
const isLeftSigner = isSignerLeaf(topology.left)
const isRightSigner = isSignerLeaf(topology.right)
if (trim && left.weight.eq(0) && right.weight.eq(0) && !isLeftSigner && !isRightSigner) {
return {

@@ -380,3 +383,3 @@ // We don't need to include anything for this node

if (trim && right.weight.eq(0)) {
if (trim && right.weight.eq(0) && !isRightSigner) {
return {

@@ -393,3 +396,3 @@ // The right node doesn't have any weight

if (trim && left.weight.eq(0)) {
if (trim && left.weight.eq(0) && !isLeftSigner) {
return {

@@ -670,3 +673,3 @@ // The left node doesn't have any weight

export function encodeSignature(
decoded: UnrecoveredChainedSignature | ChainedSignature | UnrecoveredSignature | Signature | ethers.BytesLike
decoded: UnrecoveredChainedSignature | ChainedSignature | UnrecoveredSignature | Signature | ethers.BytesLike,
): string {

@@ -686,3 +689,3 @@ if (ethers.utils.isBytesLike(decoded)) return ethers.utils.hexlify(decoded)

case SignatureType.Legacy:
if (body.threshold > 255) {
if (ethers.BigNumber.from(body.threshold).gt(255)) {
throw new Error(`Legacy signature threshold is too large: ${body.threshold} (max 255)`)

@@ -817,2 +820,135 @@ }

export function subdigestsOfDecoded(utopology: UnrecoveredTopology): string[] {
if (isUnrecoveredNode(utopology)) {
return [...subdigestsOfDecoded(utopology.left), ...subdigestsOfDecoded(utopology.right)]
}
if (isUnrecoveredNestedLeaf(utopology)) {
return subdigestsOfDecoded(utopology.tree)
}
if (isSubdigestLeaf(utopology)) {
return [utopology.subdigest]
}
return []
}
export async function trimSignature(signature: string | UnrecoveredSignature): Promise<string> {
const decoded = typeof signature === 'string' ? decodeSignature(signature) : signature
if (isUnrecoveredChainedSignature(decoded)) {
// We need to trim every suffix AND the main signature
const trimmed = await Promise.all([
trimSignature({ ...decoded, suffix: undefined } as UnrecoveredSignature),
...decoded.suffix.map((s) => trimSignature(s))
])
return encodeChain(trimmed[0], trimmed.slice(1))
}
const { trimmed } = await trimUnrecoveredTree(decoded.decoded.tree)
return encodeSignature({ ...decoded, decoded: { ...decoded.decoded, tree: trimmed }})
}
export async function trimUnrecoveredTree(tree: UnrecoveredTopology, trimStaticDigest: boolean = true): Promise<{
weight: number,
trimmed: UnrecoveredTopology
}> {
if (isUnrecoveredNode(tree)) {
const [left, right] = await Promise.all([
trimUnrecoveredTree(tree.left),
trimUnrecoveredTree(tree.right)
])
if (left.weight === 0 && right.weight === 0) {
try {
// If both weights are 0 then it means we don't have any signatures yet
// because of that, we should be able to "recover" the tree with any subdigest
// and still get the valid node hash (there shouldn't be any signatures to verify)
const recovered = await recoverTopology(tree, ethers.constants.HashZero, undefined as any)
return {
weight: 0,
trimmed: {
nodeHash: hashNode(recovered)
} as NodeLeaf
}
} catch {
// If something fails it's more likely because some signatures have sneaked in
// in that case we should keep this node
}
} else {
return {
weight: left.weight + right.weight,
trimmed: {
left: left.trimmed,
right: right.trimmed
} as UnrecoveredNode
}
}
}
if (isUnrecoveredNestedLeaf(tree)) {
const trimmed = await trimUnrecoveredTree(tree.tree)
if (trimmed.weight === 0) {
try {
// If the nested leaf is empty, we can recover it with any subdigest
// and still get the valid node hash (there shouldn't be any signatures to verify)
const recovered = await recoverTopology(tree, ethers.constants.HashZero, undefined as any)
return {
weight: 0,
trimmed: {
nodeHash: hashNode(recovered)
} as NodeLeaf
}
} catch {
// If something fails it's more likely because some signatures have sneaked in
// in that case we should keep this node
}
}
return {
weight: trimmed.weight,
trimmed: {
weight: tree.weight,
threshold: tree.threshold,
tree: trimmed.trimmed
} as UnrecoveredNestedLeaf
}
}
// Hash nodes can be encoded as signer leaves if they have a weight below
// 256, most likely the are signer leaves wrongly encoded
if (isNodeLeaf(tree) && isEncodedSignerLeaf(tree.nodeHash)) {
return {
weight: 0,
trimmed: {
...decodeSignerLeaf(tree.nodeHash),
} as SignerLeaf
}
}
if (isUnrecoveredSignatureLeaf(tree) || (isSignerLeaf(tree) && tree.signature !== undefined)) {
return {
weight: ethers.BigNumber.from(tree.weight).toNumber(),
trimmed: tree
}
}
if (!trimStaticDigest && isSubdigestLeaf(tree)) {
return {
weight: +Infinity,
trimmed: tree
}
}
return {
weight: 0,
trimmed: tree
}
}
export const SignatureCoder: base.SignatureCoder<

@@ -831,2 +967,6 @@ WalletConfig,

trim: (data: string): Promise<string> => {
return trimSignature(data)
},
supportsNoChainId: true,

@@ -833,0 +973,0 @@

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc