@agenticprimitives/agent-account 0.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +122 -0
- package/dist/abis.d.ts +543 -0
- package/dist/abis.d.ts.map +1 -0
- package/dist/abis.js +261 -0
- package/dist/abis.js.map +1 -0
- package/dist/bundler-client.d.ts +62 -0
- package/dist/bundler-client.d.ts.map +1 -0
- package/dist/bundler-client.js +95 -0
- package/dist/bundler-client.js.map +1 -0
- package/dist/client.d.ts +224 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +473 -0
- package/dist/client.js.map +1 -0
- package/dist/execute.d.ts +39 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +72 -0
- package/dist/execute.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/quorum.d.ts +62 -0
- package/dist/quorum.d.ts.map +1 -0
- package/dist/quorum.js +103 -0
- package/dist/quorum.js.map +1 -0
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/webauthn-signature.d.ts +34 -0
- package/dist/webauthn-signature.d.ts.map +1 -0
- package/dist/webauthn-signature.js +51 -0
- package/dist/webauthn-signature.js.map +1 -0
- package/package.json +57 -0
- package/spec.md +6 -0
package/dist/quorum.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type Address, type Hex } from 'viem';
|
|
2
|
+
/**
|
|
3
|
+
* One slot in the Safe-compatible packed signature blob. Each slot is
|
|
4
|
+
* 65 bytes: `{32 r}{32 s}{1 v}`. The `v` byte discriminates the
|
|
5
|
+
* verification path per spec 207 § 5 (see SignatureSlotRecovery):
|
|
6
|
+
*
|
|
7
|
+
* v ∈ {27, 28} → ECDSA over the raw payload hash
|
|
8
|
+
* v > 30 → eth_sign / EIP-191-wrapped ECDSA (v - 4 = recovery)
|
|
9
|
+
* v == 1 → pre-approved hash; `r` holds the signer
|
|
10
|
+
* (left-padded), `s` unused
|
|
11
|
+
* v == 0 → ERC-1271 contract sig; `r` holds signer
|
|
12
|
+
* (left-padded), `s` holds the byte offset into the
|
|
13
|
+
* blob where the length-prefixed dynamic sig tail
|
|
14
|
+
* starts. (Not generated by this helper today —
|
|
15
|
+
* build the blob manually if you need this path.)
|
|
16
|
+
*/
|
|
17
|
+
export interface SafeSignatureSlot {
|
|
18
|
+
/** Address that signed (or the contract address for v=0). */
|
|
19
|
+
signer: Address;
|
|
20
|
+
/** Raw 65-byte ECDSA signature `{r}{s}{v}` from `viem.sign` or
|
|
21
|
+
* `vm.sign`. The packer extracts the (r, s, v) bytes and writes
|
|
22
|
+
* them into the appropriate slot ordering after sort. */
|
|
23
|
+
signature: Hex;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Pack signature slots into Safe's `checkSignatures` blob format
|
|
27
|
+
* (sorted-ascending by signer address — the anti-duplicate scheme).
|
|
28
|
+
*
|
|
29
|
+
* Caller MUST provide slots whose `signature` bytes are 65-byte ECDSA
|
|
30
|
+
* (r/s/v). The packer doesn't re-sign — it just sorts + concatenates.
|
|
31
|
+
* For non-ECDSA slot types (v=0 ERC-1271 with a dynamic tail; v=1
|
|
32
|
+
* pre-approved hash), build the blob via `encodePacked` directly with
|
|
33
|
+
* the per-slot conventions documented in `SafeSignatureSlot.v`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function packSafeSignatures(slots: SafeSignatureSlot[]): Hex;
|
|
36
|
+
/**
|
|
37
|
+
* Verbs used in `AgentAccount._adminPayloadHash` (packages/contracts/src/
|
|
38
|
+
* AgentAccount.sol). Bound to the payload alongside (proposalId,
|
|
39
|
+
* action, args, eta, address, chainid) so a propose sig can't be
|
|
40
|
+
* replayed as an execute sig + sigs don't cross-replay between
|
|
41
|
+
* accounts or chains.
|
|
42
|
+
*/
|
|
43
|
+
export declare const ADMIN_VERB_PROPOSE: Hex;
|
|
44
|
+
export declare const ADMIN_VERB_EXECUTE: Hex;
|
|
45
|
+
export declare const ADMIN_VERB_CANCEL: Hex;
|
|
46
|
+
/**
|
|
47
|
+
* Match `AgentAccount._adminPayloadHash` exactly. Verbs are
|
|
48
|
+
* `bytes32("ADMIN_PROPOSE" | "ADMIN_EXECUTE" | "ADMIN_CANCEL")` —
|
|
49
|
+
* use the `ADMIN_VERB_*` constants below, NOT raw strings, because
|
|
50
|
+
* `bytes32(stringLiteral)` packs from the LEFT in Solidity and the
|
|
51
|
+
* SDK must match the exact byte layout.
|
|
52
|
+
*/
|
|
53
|
+
export declare function computeAdminPayloadHash(args: {
|
|
54
|
+
verb: 'PROPOSE' | 'EXECUTE' | 'CANCEL';
|
|
55
|
+
proposalId: bigint;
|
|
56
|
+
action: number;
|
|
57
|
+
callArgs: Hex;
|
|
58
|
+
eta: bigint;
|
|
59
|
+
account: Address;
|
|
60
|
+
chainId: bigint;
|
|
61
|
+
}): Hex;
|
|
62
|
+
//# sourceMappingURL=quorum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quorum.d.ts","sourceRoot":"","sources":["../src/quorum.ts"],"names":[],"mappings":"AAaA,OAAO,EAIL,KAAK,OAAO,EACZ,KAAK,GAAG,EACT,MAAM,MAAM,CAAC;AAId;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,iBAAiB;IAChC,6DAA6D;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB;;8DAE0D;IAC1D,SAAS,EAAE,GAAG,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,GAAG,CA8BlE;AAID;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,GAA6C,CAAC;AAC/E,eAAO,MAAM,kBAAkB,EAAE,GAA2C,CAAC;AAC7E,eAAO,MAAM,iBAAiB,EAAE,GAA4C,CAAC;AAE7E;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,GAAG,CAoCN"}
|
package/dist/quorum.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Spec 207 threshold-policy + quorum utilities.
|
|
2
|
+
//
|
|
3
|
+
// `packSafeSignatures` produces the Safe-compatible 65-byte-per-slot
|
|
4
|
+
// signature blob that both `QuorumEnforcer.beforeHook` (caveat path)
|
|
5
|
+
// and `AgentAccount._verifyQuorum` (admin/recovery path) expect.
|
|
6
|
+
// `computeAdminPayloadHash` mirrors `AgentAccount._adminPayloadHash`
|
|
7
|
+
// off-chain so SDK callers can derive the digest they need to sign
|
|
8
|
+
// without a chain round-trip.
|
|
9
|
+
//
|
|
10
|
+
// Both utilities are pure — no providers, no chain reads. The
|
|
11
|
+
// `AgentAccountClient` admin methods use them internally; consumers
|
|
12
|
+
// who want to build their own admin tooling can import them directly.
|
|
13
|
+
import { encodeAbiParameters, encodePacked, keccak256, } from 'viem';
|
|
14
|
+
/**
|
|
15
|
+
* Pack signature slots into Safe's `checkSignatures` blob format
|
|
16
|
+
* (sorted-ascending by signer address — the anti-duplicate scheme).
|
|
17
|
+
*
|
|
18
|
+
* Caller MUST provide slots whose `signature` bytes are 65-byte ECDSA
|
|
19
|
+
* (r/s/v). The packer doesn't re-sign — it just sorts + concatenates.
|
|
20
|
+
* For non-ECDSA slot types (v=0 ERC-1271 with a dynamic tail; v=1
|
|
21
|
+
* pre-approved hash), build the blob via `encodePacked` directly with
|
|
22
|
+
* the per-slot conventions documented in `SafeSignatureSlot.v`.
|
|
23
|
+
*/
|
|
24
|
+
export function packSafeSignatures(slots) {
|
|
25
|
+
if (slots.length === 0) {
|
|
26
|
+
throw new Error('packSafeSignatures: at least one slot required');
|
|
27
|
+
}
|
|
28
|
+
// Validate sig shapes before sorting.
|
|
29
|
+
for (const s of slots) {
|
|
30
|
+
const bytes = s.signature.startsWith('0x') ? s.signature.slice(2) : s.signature;
|
|
31
|
+
if (bytes.length !== 130) {
|
|
32
|
+
throw new Error(`packSafeSignatures: signature for ${s.signer} must be 65 bytes (130 hex chars); got ${bytes.length}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Sort ascending by signer address (case-insensitive — addresses are
|
|
36
|
+
// sometimes mixed-case via checksum normalisation).
|
|
37
|
+
const sorted = [...slots].sort((a, b) => a.signer.toLowerCase() < b.signer.toLowerCase() ? -1 : 1);
|
|
38
|
+
// Reject duplicate signers — the on-chain verifier would catch this
|
|
39
|
+
// anyway, but failing early is friendlier.
|
|
40
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
41
|
+
if (sorted[i].signer.toLowerCase() === sorted[i - 1].signer.toLowerCase()) {
|
|
42
|
+
throw new Error(`packSafeSignatures: duplicate signer ${sorted[i].signer}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
let out = '0x';
|
|
46
|
+
for (const s of sorted) {
|
|
47
|
+
out += s.signature.replace(/^0x/, '');
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
// ─── Admin payload-hash derivation ───────────────────────────────────
|
|
52
|
+
/**
|
|
53
|
+
* Verbs used in `AgentAccount._adminPayloadHash` (packages/contracts/src/
|
|
54
|
+
* AgentAccount.sol). Bound to the payload alongside (proposalId,
|
|
55
|
+
* action, args, eta, address, chainid) so a propose sig can't be
|
|
56
|
+
* replayed as an execute sig + sigs don't cross-replay between
|
|
57
|
+
* accounts or chains.
|
|
58
|
+
*/
|
|
59
|
+
export const ADMIN_VERB_PROPOSE = '0x41444d494e5f50524f504f5345'; // bytes32("ADMIN_PROPOSE") — viem encodes properly
|
|
60
|
+
export const ADMIN_VERB_EXECUTE = '0x41444d494e5f455845435554'; // bytes32("ADMIN_EXECUTE")
|
|
61
|
+
export const ADMIN_VERB_CANCEL = '0x41444d494e5f43414e43454c'; // bytes32("ADMIN_CANCEL")
|
|
62
|
+
/**
|
|
63
|
+
* Match `AgentAccount._adminPayloadHash` exactly. Verbs are
|
|
64
|
+
* `bytes32("ADMIN_PROPOSE" | "ADMIN_EXECUTE" | "ADMIN_CANCEL")` —
|
|
65
|
+
* use the `ADMIN_VERB_*` constants below, NOT raw strings, because
|
|
66
|
+
* `bytes32(stringLiteral)` packs from the LEFT in Solidity and the
|
|
67
|
+
* SDK must match the exact byte layout.
|
|
68
|
+
*/
|
|
69
|
+
export function computeAdminPayloadHash(args) {
|
|
70
|
+
// bytes32(string) in Solidity: left-justified, zero-padded right.
|
|
71
|
+
// Compute via encodePacked + hex-padding.
|
|
72
|
+
const verbBytes = new TextEncoder().encode(`ADMIN_${args.verb}`);
|
|
73
|
+
if (verbBytes.length > 32) {
|
|
74
|
+
throw new Error(`computeAdminPayloadHash: verb too long: ADMIN_${args.verb}`);
|
|
75
|
+
}
|
|
76
|
+
const padded = new Uint8Array(32);
|
|
77
|
+
padded.set(verbBytes, 0);
|
|
78
|
+
let verbHex = '0x';
|
|
79
|
+
for (const b of padded)
|
|
80
|
+
verbHex += b.toString(16).padStart(2, '0');
|
|
81
|
+
const callArgsHash = keccak256(args.callArgs);
|
|
82
|
+
return keccak256(encodeAbiParameters([
|
|
83
|
+
{ type: 'bytes32' }, // verb
|
|
84
|
+
{ type: 'uint256' }, // proposalId
|
|
85
|
+
{ type: 'uint8' }, // action
|
|
86
|
+
{ type: 'bytes32' }, // keccak256(args)
|
|
87
|
+
{ type: 'uint64' }, // eta
|
|
88
|
+
{ type: 'address' }, // address(account)
|
|
89
|
+
{ type: 'uint256' }, // chainId
|
|
90
|
+
], [
|
|
91
|
+
verbHex,
|
|
92
|
+
args.proposalId,
|
|
93
|
+
args.action,
|
|
94
|
+
callArgsHash,
|
|
95
|
+
args.eta,
|
|
96
|
+
args.account,
|
|
97
|
+
args.chainId,
|
|
98
|
+
]));
|
|
99
|
+
}
|
|
100
|
+
// Suppress unused-import warning while the encodePacked path stays
|
|
101
|
+
// reserved for future v=0 / v=1 slot helpers.
|
|
102
|
+
void encodePacked;
|
|
103
|
+
//# sourceMappingURL=quorum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quorum.js","sourceRoot":"","sources":["../src/quorum.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Address, Hex } from '@agenticprimitives/types';
|
|
2
|
+
export type { Address, Hex };
|
|
3
|
+
export interface UserOperation {
|
|
4
|
+
sender: Address;
|
|
5
|
+
nonce: bigint;
|
|
6
|
+
initCode: Hex;
|
|
7
|
+
callData: Hex;
|
|
8
|
+
callGasLimit: bigint;
|
|
9
|
+
verificationGasLimit: bigint;
|
|
10
|
+
preVerificationGas: bigint;
|
|
11
|
+
maxFeePerGas: bigint;
|
|
12
|
+
maxPriorityFeePerGas: bigint;
|
|
13
|
+
paymasterAndData: Hex;
|
|
14
|
+
signature: Hex;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAE7D,YAAY,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAE7B,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,GAAG,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,GAAG,CAAC;IACtB,SAAS,EAAE,GAAG,CAAC;CAChB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebAuthn on-chain signature wire format.
|
|
3
|
+
*
|
|
4
|
+
* Encodes a structured `WebAuthnAssertion` (produced by the ceremony in
|
|
5
|
+
* `@agenticprimitives/connect-auth/passkey`) into the byte layout
|
|
6
|
+
* `AgentAccount._validateSig` dispatches on:
|
|
7
|
+
*
|
|
8
|
+
* 0x01 || abi.encode(Assertion)
|
|
9
|
+
*
|
|
10
|
+
* where `Assertion` matches `WebAuthnLib.Assertion` in the Solidity
|
|
11
|
+
* source (see packages/contracts/src/libraries/WebAuthnLib.sol).
|
|
12
|
+
*
|
|
13
|
+
* Doctrine: this is the agent-account substrate's signature dispatch.
|
|
14
|
+
* The auth-method ceremony (DER parsing, COSE attestation, challenge
|
|
15
|
+
* encoding) lives in connect-auth. agent-account ships only the
|
|
16
|
+
* on-chain wire-format encoder.
|
|
17
|
+
*/
|
|
18
|
+
import type { WebAuthnAssertion } from '@agenticprimitives/connect-auth/passkey';
|
|
19
|
+
/** First byte of the on-chain WebAuthn signature blob — matches
|
|
20
|
+
* `SIG_TYPE_WEBAUTHN = 0x01` in AgentAccount.sol. */
|
|
21
|
+
export declare const SIG_TYPE_WEBAUTHN: `0x${string}`;
|
|
22
|
+
/** ABI-encode the assertion struct (without the leading type byte). */
|
|
23
|
+
export declare function encodeAssertion(a: WebAuthnAssertion): `0x${string}`;
|
|
24
|
+
/**
|
|
25
|
+
* Encode the assertion as a complete UserOp / ERC-1271 signature blob:
|
|
26
|
+
*
|
|
27
|
+
* 0x01 || abi.encode(Assertion)
|
|
28
|
+
*
|
|
29
|
+
* This is what `AgentAccount._validateSig` reads — the leading byte
|
|
30
|
+
* selects `SIG_TYPE_WEBAUTHN` and the remainder is the ABI-encoded
|
|
31
|
+
* `WebAuthnLib.Assertion` struct.
|
|
32
|
+
*/
|
|
33
|
+
export declare function encodeWebAuthnSignature(a: WebAuthnAssertion): `0x${string}`;
|
|
34
|
+
//# sourceMappingURL=webauthn-signature.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webauthn-signature.d.ts","sourceRoot":"","sources":["../src/webauthn-signature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAEjF;sDACsD;AACtD,eAAO,MAAM,iBAAiB,EAAE,KAAK,MAAM,EAAW,CAAC;AAEvD,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,CAAC,EAAE,iBAAiB,GAAG,KAAK,MAAM,EAAE,CAkBnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,iBAAiB,GAAG,KAAK,MAAM,EAAE,CAE3E"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebAuthn on-chain signature wire format.
|
|
3
|
+
*
|
|
4
|
+
* Encodes a structured `WebAuthnAssertion` (produced by the ceremony in
|
|
5
|
+
* `@agenticprimitives/connect-auth/passkey`) into the byte layout
|
|
6
|
+
* `AgentAccount._validateSig` dispatches on:
|
|
7
|
+
*
|
|
8
|
+
* 0x01 || abi.encode(Assertion)
|
|
9
|
+
*
|
|
10
|
+
* where `Assertion` matches `WebAuthnLib.Assertion` in the Solidity
|
|
11
|
+
* source (see packages/contracts/src/libraries/WebAuthnLib.sol).
|
|
12
|
+
*
|
|
13
|
+
* Doctrine: this is the agent-account substrate's signature dispatch.
|
|
14
|
+
* The auth-method ceremony (DER parsing, COSE attestation, challenge
|
|
15
|
+
* encoding) lives in connect-auth. agent-account ships only the
|
|
16
|
+
* on-chain wire-format encoder.
|
|
17
|
+
*/
|
|
18
|
+
import { encodeAbiParameters, concat } from 'viem';
|
|
19
|
+
/** First byte of the on-chain WebAuthn signature blob — matches
|
|
20
|
+
* `SIG_TYPE_WEBAUTHN = 0x01` in AgentAccount.sol. */
|
|
21
|
+
export const SIG_TYPE_WEBAUTHN = '0x01';
|
|
22
|
+
/** ABI-encode the assertion struct (without the leading type byte). */
|
|
23
|
+
export function encodeAssertion(a) {
|
|
24
|
+
return encodeAbiParameters([
|
|
25
|
+
{
|
|
26
|
+
type: 'tuple',
|
|
27
|
+
components: [
|
|
28
|
+
{ name: 'authenticatorData', type: 'bytes' },
|
|
29
|
+
{ name: 'clientDataJSON', type: 'string' },
|
|
30
|
+
{ name: 'challengeIndex', type: 'uint256' },
|
|
31
|
+
{ name: 'typeIndex', type: 'uint256' },
|
|
32
|
+
{ name: 'r', type: 'uint256' },
|
|
33
|
+
{ name: 's', type: 'uint256' },
|
|
34
|
+
{ name: 'credentialIdDigest', type: 'bytes32' },
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
], [a]);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Encode the assertion as a complete UserOp / ERC-1271 signature blob:
|
|
41
|
+
*
|
|
42
|
+
* 0x01 || abi.encode(Assertion)
|
|
43
|
+
*
|
|
44
|
+
* This is what `AgentAccount._validateSig` reads — the leading byte
|
|
45
|
+
* selects `SIG_TYPE_WEBAUTHN` and the remainder is the ABI-encoded
|
|
46
|
+
* `WebAuthnLib.Assertion` struct.
|
|
47
|
+
*/
|
|
48
|
+
export function encodeWebAuthnSignature(a) {
|
|
49
|
+
return concat([SIG_TYPE_WEBAUTHN, encodeAssertion(a)]);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=webauthn-signature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webauthn-signature.js","sourceRoot":"","sources":["../src/webauthn-signature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAGnD;sDACsD;AACtD,MAAM,CAAC,MAAM,iBAAiB,GAAkB,MAAM,CAAC;AAEvD,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAAC,CAAoB;IAClD,OAAO,mBAAmB,CACxB;QACE;YACE,IAAI,EAAE,OAAO;YACb,UAAU,EAAE;gBACV,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,OAAO,EAAE;gBAC5C,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1C,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,EAAE;gBAC3C,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE;gBACtC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE;gBAC9B,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE;gBAC9B,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,SAAS,EAAE;aAChD;SACF;KACF,EACD,CAAC,CAAC,CAAC,CACJ,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,CAAoB;IAC1D,OAAO,MAAM,CAAC,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agenticprimitives/agent-account",
|
|
3
|
+
"version": "0.1.0-alpha.2",
|
|
4
|
+
"description": "ERC-4337 smart-account substrate: deterministic addressing, factory deployment, ERC-1271 signing, UserOp building.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/agentictrustlabs/agenticprimitives.git",
|
|
9
|
+
"directory": "packages/agent-account"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/agentictrustlabs/agenticprimitives/tree/master/packages/agent-account",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/agentictrustlabs/agenticprimitives/issues"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"dist",
|
|
27
|
+
"spec.md",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc -p tsconfig.build.json",
|
|
32
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:unit": "vitest run test/unit",
|
|
35
|
+
"test:integration": "vitest run test/integration --passWithNoTests",
|
|
36
|
+
"test:watch": "vitest",
|
|
37
|
+
"clean": "rm -rf dist"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"@agenticprimitives/connect-auth": "workspace:*",
|
|
44
|
+
"@agenticprimitives/types": "workspace:*",
|
|
45
|
+
"viem": "^2.50.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"vitest": "^2.1.0"
|
|
49
|
+
},
|
|
50
|
+
"keywords": [
|
|
51
|
+
"erc-4337",
|
|
52
|
+
"smart-account",
|
|
53
|
+
"account-abstraction",
|
|
54
|
+
"erc-1271",
|
|
55
|
+
"agentic"
|
|
56
|
+
]
|
|
57
|
+
}
|