@run402/sdk 4.120.0 → 4.122.0
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/README.md +1 -1
- package/core-dist/profiles.d.ts +2 -0
- package/core-dist/wallet-auth.d.ts +30 -0
- package/core-dist/wallet-auth.js +77 -38
- package/core-dist/wallet.d.ts +22 -1
- package/core-dist/wallet.js +21 -0
- package/dist/credentials.d.ts +15 -1
- package/dist/credentials.d.ts.map +1 -1
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +22 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/namespaces/deploy.d.ts.map +1 -1
- package/dist/namespaces/deploy.js +3 -0
- package/dist/namespaces/deploy.js.map +1 -1
- package/dist/namespaces/deploy.types.d.ts +4 -2
- package/dist/namespaces/deploy.types.d.ts.map +1 -1
- package/dist/namespaces/deploy.types.js +4 -0
- package/dist/namespaces/deploy.types.js.map +1 -1
- package/dist/namespaces/pay.d.ts +7 -0
- package/dist/namespaces/pay.d.ts.map +1 -1
- package/dist/namespaces/pay.js +5 -0
- package/dist/namespaces/pay.js.map +1 -1
- package/dist/node/_paid-stack.d.ts +26 -3
- package/dist/node/_paid-stack.d.ts.map +1 -1
- package/dist/node/_paid-stack.js +19 -0
- package/dist/node/_paid-stack.js.map +1 -1
- package/dist/node/ci.d.ts +1 -1
- package/dist/node/ci.d.ts.map +1 -1
- package/dist/node/ci.js +8 -6
- package/dist/node/ci.js.map +1 -1
- package/dist/node/credentials.d.ts.map +1 -1
- package/dist/node/credentials.js +5 -4
- package/dist/node/credentials.js.map +1 -1
- package/dist/node/index.d.ts +2 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +2 -1
- package/dist/node/index.js.map +1 -1
- package/dist/node/lightning-paid-fetch.d.ts.map +1 -1
- package/dist/node/lightning-paid-fetch.js +2 -0
- package/dist/node/lightning-paid-fetch.js.map +1 -1
- package/dist/node/mpp-pay-executor.d.ts +40 -0
- package/dist/node/mpp-pay-executor.d.ts.map +1 -0
- package/dist/node/mpp-pay-executor.js +352 -0
- package/dist/node/mpp-pay-executor.js.map +1 -0
- package/dist/node/org-adopt.d.ts +1 -1
- package/dist/node/org-adopt.d.ts.map +1 -1
- package/dist/node/org-adopt.js +9 -7
- package/dist/node/org-adopt.js.map +1 -1
- package/dist/node/paid-fetch.d.ts +2 -1
- package/dist/node/paid-fetch.d.ts.map +1 -1
- package/dist/node/paid-fetch.js +50 -22
- package/dist/node/paid-fetch.js.map +1 -1
- package/dist/node/payment-attempts.d.ts +2 -2
- package/dist/node/payment-attempts.d.ts.map +1 -1
- package/dist/node/payment-attempts.js +2 -2
- package/dist/node/payment-attempts.js.map +1 -1
- package/dist/node/payment-offers.d.ts +35 -0
- package/dist/node/payment-offers.d.ts.map +1 -0
- package/dist/node/payment-offers.js +145 -0
- package/dist/node/payment-offers.js.map +1 -0
- package/dist/node/signers/index.d.ts +26 -0
- package/dist/node/signers/index.d.ts.map +1 -0
- package/dist/node/signers/index.js +35 -0
- package/dist/node/signers/index.js.map +1 -0
- package/dist/node/signers/kms.d.ts +54 -0
- package/dist/node/signers/kms.d.ts.map +1 -0
- package/dist/node/signers/kms.js +236 -0
- package/dist/node/signers/kms.js.map +1 -0
- package/dist/node/wallets-send.d.ts +62 -0
- package/dist/node/wallets-send.d.ts.map +1 -0
- package/dist/node/wallets-send.js +149 -0
- package/dist/node/wallets-send.js.map +1 -0
- package/dist/node/wallets.d.ts +33 -5
- package/dist/node/wallets.d.ts.map +1 -1
- package/dist/node/wallets.js +78 -12
- package/dist/node/wallets.js.map +1 -1
- package/dist/secret-gate.d.ts +1 -1
- package/dist/secret-gate.d.ts.map +1 -1
- package/dist/secret-gate.js +7 -2
- package/dist/secret-gate.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment-offers.d.ts","sourceRoot":"","sources":["../../src/node/payment-offers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;IACzB,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAID,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,EAAE,CAEhE;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,EAAE,CAgB7D;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACzC;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,kBAAkB,EAAE,CAYtE;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,EAAE,CAO5D;AAWD,iGAAiG;AACjG,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,GAAG,IAAI,CAIpE;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,UAAU,EAAE,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,IAAI,CAMtH"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every payment a 402 offers, whichever protocol states it: x402 entries from
|
|
3
|
+
* `PAYMENT-REQUIRED`, MPP challenges from `WWW-Authenticate: Payment`. The
|
|
4
|
+
* wrong-rail error lists these and names the rail switch that would pay the
|
|
5
|
+
* first one (spec `tenant-x402-payment-client-surface`).
|
|
6
|
+
*
|
|
7
|
+
* Parsed without the paid stack: an x402-only install has no `mppx`, and the
|
|
8
|
+
* error still has to say what the seller wanted.
|
|
9
|
+
*/
|
|
10
|
+
const LNBTC_PREFIX = "lnbtc:";
|
|
11
|
+
export function paymentOffers(response) {
|
|
12
|
+
return [...x402Offers(response), ...mppOffers(response)];
|
|
13
|
+
}
|
|
14
|
+
export function x402Offers(response) {
|
|
15
|
+
const header = response.headers.get("PAYMENT-REQUIRED");
|
|
16
|
+
if (!header)
|
|
17
|
+
return [];
|
|
18
|
+
try {
|
|
19
|
+
// base64url decoding accepts both alphabets, so it reads either seller encoding.
|
|
20
|
+
const decoded = JSON.parse(Buffer.from(header, "base64url").toString("utf8"));
|
|
21
|
+
if (!Array.isArray(decoded.accepts))
|
|
22
|
+
return [];
|
|
23
|
+
return decoded.accepts.flatMap((accept) => {
|
|
24
|
+
const entry = accept;
|
|
25
|
+
return typeof entry?.scheme === "string"
|
|
26
|
+
? [{ protocol: "x402", method: entry.scheme, network: typeof entry.network === "string" ? entry.network : null }]
|
|
27
|
+
: [];
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** The `Payment` challenges in `WWW-Authenticate`, with their decoded `request`. */
|
|
35
|
+
export function mppChallenges(response) {
|
|
36
|
+
const header = response.headers.get("WWW-Authenticate");
|
|
37
|
+
if (!header)
|
|
38
|
+
return [];
|
|
39
|
+
return splitPaymentChallenges(header).flatMap((params) => {
|
|
40
|
+
if (!params.method || !params.intent)
|
|
41
|
+
return [];
|
|
42
|
+
return [{
|
|
43
|
+
...(params.id ? { id: params.id } : {}),
|
|
44
|
+
method: params.method,
|
|
45
|
+
intent: params.intent,
|
|
46
|
+
request: decodeRequest(params.request),
|
|
47
|
+
}];
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export function mppOffers(response) {
|
|
51
|
+
return mppChallenges(response).map((challenge) => ({
|
|
52
|
+
protocol: "mpp",
|
|
53
|
+
method: challenge.method,
|
|
54
|
+
intent: challenge.intent,
|
|
55
|
+
network: mppNetwork(challenge),
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
/** `eip155:<chainId>` for a Tempo charge; the request's own network otherwise. */
|
|
59
|
+
function mppNetwork(challenge) {
|
|
60
|
+
const details = challenge.request?.methodDetails;
|
|
61
|
+
if (challenge.method === "tempo" && (typeof details?.chainId === "number" || typeof details?.chainId === "string")) {
|
|
62
|
+
return `eip155:${String(details.chainId)}`;
|
|
63
|
+
}
|
|
64
|
+
return typeof details?.network === "string" ? details.network : null;
|
|
65
|
+
}
|
|
66
|
+
/** The rail that pays an offer: x402 EVM entries, MPP Tempo, and Lightning (either protocol). */
|
|
67
|
+
export function railForOffer(offer) {
|
|
68
|
+
if (offer.method === "lightning" || offer.network?.startsWith(LNBTC_PREFIX))
|
|
69
|
+
return "lightning";
|
|
70
|
+
if (offer.protocol === "mpp")
|
|
71
|
+
return offer.method === "tempo" ? "mpp" : null;
|
|
72
|
+
return offer.method === "exact" ? "x402" : null;
|
|
73
|
+
}
|
|
74
|
+
/** The first offer's rail, when it is not the configured one. */
|
|
75
|
+
export function switchRailFor(offers, configured) {
|
|
76
|
+
for (const offer of offers) {
|
|
77
|
+
const rail = railForOffer(offer);
|
|
78
|
+
if (rail && rail !== configured)
|
|
79
|
+
return rail;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* RFC 9110 auth-params for every `Payment` scheme in the header. A header may
|
|
85
|
+
* carry several challenges, comma-joined; a new challenge starts where a
|
|
86
|
+
* scheme token is followed by a space instead of `=`.
|
|
87
|
+
*/
|
|
88
|
+
function splitPaymentChallenges(header) {
|
|
89
|
+
const challenges = [];
|
|
90
|
+
let index = 0;
|
|
91
|
+
while (index < header.length) {
|
|
92
|
+
index = skip(header, index, " \t,");
|
|
93
|
+
const token = readToken(header, index);
|
|
94
|
+
if (!token)
|
|
95
|
+
break;
|
|
96
|
+
index += token.length;
|
|
97
|
+
if (header[index] !== "=") {
|
|
98
|
+
challenges.push({ scheme: token.toLowerCase(), params: {} });
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const current = challenges[challenges.length - 1];
|
|
102
|
+
const parsed = readParamValue(header, index + 1);
|
|
103
|
+
index = parsed.next;
|
|
104
|
+
if (current)
|
|
105
|
+
current.params[token.toLowerCase()] = parsed.value;
|
|
106
|
+
}
|
|
107
|
+
return challenges.filter((challenge) => challenge.scheme === "payment").map((challenge) => challenge.params);
|
|
108
|
+
}
|
|
109
|
+
function skip(value, index, chars) {
|
|
110
|
+
while (index < value.length && chars.includes(value[index]))
|
|
111
|
+
index += 1;
|
|
112
|
+
return index;
|
|
113
|
+
}
|
|
114
|
+
function readToken(value, index) {
|
|
115
|
+
const match = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+/.exec(value.slice(index));
|
|
116
|
+
return match ? match[0] : "";
|
|
117
|
+
}
|
|
118
|
+
function readParamValue(value, index) {
|
|
119
|
+
index = skip(value, index, " \t");
|
|
120
|
+
if (value[index] !== "\"") {
|
|
121
|
+
const token = /^[^,\s]*/.exec(value.slice(index))[0];
|
|
122
|
+
return { value: token, next: index + token.length };
|
|
123
|
+
}
|
|
124
|
+
let out = "";
|
|
125
|
+
let cursor = index + 1;
|
|
126
|
+
while (cursor < value.length && value[cursor] !== "\"") {
|
|
127
|
+
if (value[cursor] === "\\" && cursor + 1 < value.length)
|
|
128
|
+
cursor += 1;
|
|
129
|
+
out += value[cursor];
|
|
130
|
+
cursor += 1;
|
|
131
|
+
}
|
|
132
|
+
return { value: out, next: cursor + 1 };
|
|
133
|
+
}
|
|
134
|
+
function decodeRequest(encoded) {
|
|
135
|
+
if (!encoded)
|
|
136
|
+
return null;
|
|
137
|
+
try {
|
|
138
|
+
const value = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
139
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=payment-offers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment-offers.js","sourceRoot":"","sources":["../../src/node/payment-offers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place a wallet becomes something that signs (spec `wallet-signers`,
|
|
3
|
+
* design D2). A key-backed wallet yields viem's local account; a signer-backed
|
|
4
|
+
* one (`wallet.json` `signer`) yields an account that signs through that
|
|
5
|
+
* signer. Every SDK signing site resolves its signer here, so a signer-backed
|
|
6
|
+
* wallet works wherever a key-backed one does.
|
|
7
|
+
*/
|
|
8
|
+
import type { LocalAccount } from "viem";
|
|
9
|
+
import type { WalletData } from "../../../core-dist/wallet.js";
|
|
10
|
+
import type { PersonalMessageSigner } from "../../../core-dist/wallet-auth.js";
|
|
11
|
+
import { type KmsAccountOptions } from "./kms.js";
|
|
12
|
+
export { adoptKmsKey, kmsAccount, kmsError, type AdoptedKmsKey, type KmsAccountOptions, type KmsClientLike } from "./kms.js";
|
|
13
|
+
export type WalletSignerKind = "local" | "aws_kms";
|
|
14
|
+
/** How a wallet signs, without loading anything. */
|
|
15
|
+
export declare function walletSignerKind(wallet: Pick<WalletData, "signer">): WalletSignerKind;
|
|
16
|
+
/** True when the wallet can sign at all (a key or a signer reference). */
|
|
17
|
+
export declare function walletCanSign(wallet: Pick<WalletData, "privateKey" | "signer"> | null | undefined): boolean;
|
|
18
|
+
export interface ResolveWalletAccountOptions extends KmsAccountOptions {
|
|
19
|
+
/** How a key-backed wallet becomes an account (the paid stack passes its own loaded viem). */
|
|
20
|
+
privateKeyToAccount?: (privateKey: `0x${string}`) => unknown;
|
|
21
|
+
}
|
|
22
|
+
/** The viem account that signs as `wallet`. */
|
|
23
|
+
export declare function resolveWalletAccount(wallet: WalletData, opts?: ResolveWalletAccountOptions): Promise<LocalAccount>;
|
|
24
|
+
/** An EIP-191 personal-message signer for `wallet` (SIWX, identity links). */
|
|
25
|
+
export declare function personalMessageSignerFor(wallet: WalletData, opts?: KmsAccountOptions): Promise<PersonalMessageSigner>;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/node/signers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE/E,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE9D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAE7H,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,SAAS,CAAC;AAEnD,oDAAoD;AACpD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,gBAAgB,CAErF;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,YAAY,GAAG,QAAQ,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE3G;AAED,MAAM,WAAW,2BAA4B,SAAQ,iBAAiB;IACpE,8FAA8F;IAC9F,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,MAAM,EAAE,KAAK,OAAO,CAAC;CAC9D;AAED,+CAA+C;AAC/C,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,GAAE,2BAAgC,GAAG,OAAO,CAAC,YAAY,CAAC,CAe5H;AAED,8EAA8E;AAC9E,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAG/H"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { LocalError } from "../../errors.js";
|
|
2
|
+
import { kmsAccount } from "./kms.js";
|
|
3
|
+
export { adoptKmsKey, kmsAccount, kmsError } from "./kms.js";
|
|
4
|
+
/** How a wallet signs, without loading anything. */
|
|
5
|
+
export function walletSignerKind(wallet) {
|
|
6
|
+
return wallet.signer ? wallet.signer.kind : "local";
|
|
7
|
+
}
|
|
8
|
+
/** True when the wallet can sign at all (a key or a signer reference). */
|
|
9
|
+
export function walletCanSign(wallet) {
|
|
10
|
+
return Boolean(wallet && (wallet.signer || wallet.privateKey));
|
|
11
|
+
}
|
|
12
|
+
/** The viem account that signs as `wallet`. */
|
|
13
|
+
export async function resolveWalletAccount(wallet, opts = {}) {
|
|
14
|
+
if (wallet.privateKey && wallet.signer) {
|
|
15
|
+
throw new LocalError("This wallet has both a private key and a signer; a wallet is backed by exactly one.", "resolving the wallet signer", {
|
|
16
|
+
code: "BAD_WALLET_FILE",
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
if (wallet.signer)
|
|
20
|
+
return kmsAccount(wallet.signer, wallet.address, opts);
|
|
21
|
+
if (wallet.privateKey) {
|
|
22
|
+
const toAccount = opts.privateKeyToAccount ?? (await import("viem/accounts")).privateKeyToAccount;
|
|
23
|
+
return toAccount(wallet.privateKey);
|
|
24
|
+
}
|
|
25
|
+
throw new LocalError("This wallet has neither a private key nor a signer.", "resolving the wallet signer", {
|
|
26
|
+
code: "BAD_WALLET_FILE",
|
|
27
|
+
next_actions: [{ type: "initialize_wallet", command: "run402 init" }],
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/** An EIP-191 personal-message signer for `wallet` (SIWX, identity links). */
|
|
31
|
+
export async function personalMessageSignerFor(wallet, opts = {}) {
|
|
32
|
+
const account = await resolveWalletAccount(wallet, opts);
|
|
33
|
+
return (message) => account.signMessage({ message });
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/node/signers/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAA0B,MAAM,UAAU,CAAC;AAE9D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAkE,MAAM,UAAU,CAAC;AAI7H,oDAAoD;AACpD,MAAM,UAAU,gBAAgB,CAAC,MAAkC;IACjE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;AACtD,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,MAAoE;IAChG,OAAO,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AACjE,CAAC;AAOD,+CAA+C;AAC/C,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAkB,EAAE,OAAoC,EAAE;IACnG,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QACvC,MAAM,IAAI,UAAU,CAAC,qFAAqF,EAAE,6BAA6B,EAAE;YACzI,IAAI,EAAE,iBAAiB;SACxB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC1E,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,IAAI,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,mBAAmB,CAAC;QAClG,OAAO,SAAS,CAAC,MAAM,CAAC,UAA2B,CAAiB,CAAC;IACvE,CAAC;IACD,MAAM,IAAI,UAAU,CAAC,qDAAqD,EAAE,6BAA6B,EAAE;QACzG,IAAI,EAAE,iBAAiB;QACvB,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;KACtE,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAkB,EAAE,OAA0B,EAAE;IAC7F,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzD,OAAO,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A wallet whose key lives in AWS KMS (spec `wallet-signers`). The key never
|
|
3
|
+
* leaves KMS: the client hashes locally, KMS signs the 32-byte digest, and the
|
|
4
|
+
* DER signature becomes an Ethereum signature with a low-s value (EIP-2) and
|
|
5
|
+
* the recovery id under which it recovers to the wallet's address. A signature
|
|
6
|
+
* that recovers to no address of this wallet is refused before anything
|
|
7
|
+
* carrying it is sent.
|
|
8
|
+
*
|
|
9
|
+
* The algorithm mirrors the gateway's `services/kms-signer.ts`; both keep the
|
|
10
|
+
* same vectors in their tests.
|
|
11
|
+
*/
|
|
12
|
+
import type { Hex, LocalAccount } from "viem";
|
|
13
|
+
import type { WalletSigner } from "../../../core-dist/wallet.js";
|
|
14
|
+
import { LocalError } from "../../errors.js";
|
|
15
|
+
import { type KmsStack } from "../_paid-stack.js";
|
|
16
|
+
/** The part of a KMS client the signer uses; tests pass a fake. */
|
|
17
|
+
export interface KmsClientLike {
|
|
18
|
+
send(command: unknown): Promise<unknown>;
|
|
19
|
+
}
|
|
20
|
+
/** Parse an ECDSA DER signature (SEQUENCE { INTEGER r, INTEGER s }). */
|
|
21
|
+
export declare function parseDerSignature(der: Uint8Array): {
|
|
22
|
+
r: bigint;
|
|
23
|
+
s: bigint;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* KMS's DER signature over `hash` → a 65-byte Ethereum signature that recovers
|
|
27
|
+
* to `address`, or `SIGNER_ADDRESS_MISMATCH`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function derToEthereumSignature(viem: Pick<KmsStack["viem"], "recoverAddress" | "serializeSignature" | "numberToHex">, der: Uint8Array, hash: Hex, address: string): Promise<Hex>;
|
|
30
|
+
/** A KMS/AWS failure as a named local error with its remedy; never renders a credential. */
|
|
31
|
+
export declare function kmsError(err: unknown, signer: WalletSigner, context: string): LocalError;
|
|
32
|
+
export interface KmsAccountOptions {
|
|
33
|
+
/** Test seam: a stack (or part of one) in place of the lazily loaded peers. */
|
|
34
|
+
stack?: KmsStack;
|
|
35
|
+
client?: KmsClientLike;
|
|
36
|
+
}
|
|
37
|
+
/** A viem account that signs through `signer` as `address`. */
|
|
38
|
+
export declare function kmsAccount(signer: WalletSigner, address: string, opts?: KmsAccountOptions): Promise<LocalAccount>;
|
|
39
|
+
export interface AdoptedKmsKey {
|
|
40
|
+
address: string;
|
|
41
|
+
key_spec: string;
|
|
42
|
+
key_usage: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Read a KMS key's public key and metadata (read-only: `GetPublicKey` only)
|
|
46
|
+
* and derive its address; `KMS_KEY_UNSUITABLE` unless it is a secp256k1
|
|
47
|
+
* signing key.
|
|
48
|
+
*/
|
|
49
|
+
export declare function adoptKmsKey(signer: WalletSigner, opts?: KmsAccountOptions): Promise<AdoptedKmsKey>;
|
|
50
|
+
/** The EVM address of a secp256k1 SubjectPublicKeyInfo (what KMS GetPublicKey returns). */
|
|
51
|
+
export declare function addressFromSpki(viem: Pick<KmsStack["viem"], "keccak256" | "getAddress">, der: Uint8Array): string;
|
|
52
|
+
/** Test seam: forget cached clients. */
|
|
53
|
+
export declare function resetKmsClientsForTests(): void;
|
|
54
|
+
//# sourceMappingURL=kms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kms.d.ts","sourceRoot":"","sources":["../../../src/node/signers/kms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAsC,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAKtF,mEAAmE;AACnE,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1C;AA0BD,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAe3E;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,aAAa,CAAC,EACrF,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,GAAG,EACT,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,CA4Bd;AAMD,4FAA4F;AAC5F,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAkDxF;AAeD,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,+DAA+D;AAC/D,wBAAsB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiD3H;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,aAAa,CAAC,CA0B5G;AAID,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,YAAY,CAAC,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,CAUjH;AAED,wCAAwC;AACxC,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { LocalError } from "../../errors.js";
|
|
2
|
+
import { PaidStackUnavailable, loadKmsStack } from "../_paid-stack.js";
|
|
3
|
+
const SECP256K1_N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n;
|
|
4
|
+
const SECP256K1_HALF_N = SECP256K1_N >> 1n;
|
|
5
|
+
/** KMS answered with something that is not an ECDSA signature. */
|
|
6
|
+
function malformed(message) {
|
|
7
|
+
return new LocalError(message, "signing with a KMS wallet", {
|
|
8
|
+
code: "KMS_SIGNATURE_MALFORMED",
|
|
9
|
+
next_actions: [{ type: "retry", why: "Retry once; if it persists, check the key is ECC_SECG_P256K1 / SIGN_VERIFY." }],
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function bytesToHex(bytes) {
|
|
13
|
+
return Buffer.from(bytes).toString("hex");
|
|
14
|
+
}
|
|
15
|
+
/** DER length at `i`: returns [length, next index]. Supports short and long form. */
|
|
16
|
+
function derLength(der, i) {
|
|
17
|
+
const first = der[i];
|
|
18
|
+
if (first === undefined)
|
|
19
|
+
throw malformed("malformed DER: truncated length");
|
|
20
|
+
if ((first & 0x80) === 0)
|
|
21
|
+
return [first, i + 1];
|
|
22
|
+
const count = first & 0x7f;
|
|
23
|
+
if (count === 0 || count > 2 || i + 1 + count > der.length)
|
|
24
|
+
throw malformed("malformed DER: bad length");
|
|
25
|
+
let len = 0;
|
|
26
|
+
for (let j = 0; j < count; j++)
|
|
27
|
+
len = (len << 8) | der[i + 1 + j];
|
|
28
|
+
return [len, i + 1 + count];
|
|
29
|
+
}
|
|
30
|
+
/** Parse an ECDSA DER signature (SEQUENCE { INTEGER r, INTEGER s }). */
|
|
31
|
+
export function parseDerSignature(der) {
|
|
32
|
+
if (der[0] !== 0x30)
|
|
33
|
+
throw malformed("malformed DER signature: not a SEQUENCE");
|
|
34
|
+
let [, i] = derLength(der, 1);
|
|
35
|
+
const readInt = () => {
|
|
36
|
+
if (der[i] !== 0x02)
|
|
37
|
+
throw malformed("malformed DER signature: expected INTEGER");
|
|
38
|
+
const [len, start] = derLength(der, i + 1);
|
|
39
|
+
if (len === 0 || start + len > der.length)
|
|
40
|
+
throw malformed("malformed DER signature: bad INTEGER");
|
|
41
|
+
const value = BigInt("0x" + bytesToHex(der.slice(start, start + len)));
|
|
42
|
+
i = start + len;
|
|
43
|
+
return value;
|
|
44
|
+
};
|
|
45
|
+
const r = readInt();
|
|
46
|
+
const s = readInt();
|
|
47
|
+
if (r === 0n || s === 0n || r >= SECP256K1_N || s >= SECP256K1_N)
|
|
48
|
+
throw malformed("malformed DER signature: out of range");
|
|
49
|
+
return { r, s };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* KMS's DER signature over `hash` → a 65-byte Ethereum signature that recovers
|
|
53
|
+
* to `address`, or `SIGNER_ADDRESS_MISMATCH`.
|
|
54
|
+
*/
|
|
55
|
+
export async function derToEthereumSignature(viem, der, hash, address) {
|
|
56
|
+
const { r, s } = parseDerSignature(der);
|
|
57
|
+
const lowS = s > SECP256K1_HALF_N ? SECP256K1_N - s : s;
|
|
58
|
+
const rHex = viem.numberToHex(r, { size: 32 });
|
|
59
|
+
const sHex = viem.numberToHex(lowS, { size: 32 });
|
|
60
|
+
const recovered = [];
|
|
61
|
+
for (const yParity of [0, 1]) {
|
|
62
|
+
const signature = viem.serializeSignature({ r: rHex, s: sHex, yParity });
|
|
63
|
+
try {
|
|
64
|
+
const candidate = await viem.recoverAddress({ hash, signature });
|
|
65
|
+
if (candidate.toLowerCase() === address.toLowerCase())
|
|
66
|
+
return signature;
|
|
67
|
+
recovered.push(candidate);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// the other recovery id
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
throw new LocalError(`The KMS key signed as ${recovered.join(" or ") || "no recoverable address"}, not as this wallet's address ${address}.`, "signing with a KMS wallet", {
|
|
74
|
+
code: "SIGNER_ADDRESS_MISMATCH",
|
|
75
|
+
details: { expected_address: address, recovered_addresses: recovered },
|
|
76
|
+
next_actions: [{
|
|
77
|
+
type: "edit_request",
|
|
78
|
+
why: "The key behind this wallet's ARN is not the key it was imported from. Re-import the right key, or check wallet.json's key_arn.",
|
|
79
|
+
}],
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function errorName(err) {
|
|
83
|
+
return err?.name === undefined ? "" : String(err.name);
|
|
84
|
+
}
|
|
85
|
+
/** A KMS/AWS failure as a named local error with its remedy; never renders a credential. */
|
|
86
|
+
export function kmsError(err, signer, context) {
|
|
87
|
+
if (err instanceof LocalError)
|
|
88
|
+
return err;
|
|
89
|
+
if (err instanceof PaidStackUnavailable) {
|
|
90
|
+
return new LocalError(`A KMS wallet needs ${err.missingPackages.join(", ")}, which is not installed.`, context, {
|
|
91
|
+
code: "KMS_SIGNER_UNAVAILABLE",
|
|
92
|
+
details: { missing_packages: err.missingPackages },
|
|
93
|
+
next_actions: [{ type: "upgrade_client", command: `npm install ${err.missingPackages.join(" ")}`, why: "Install the KMS client, then retry." }],
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const name = errorName(err);
|
|
97
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
98
|
+
if (name === "AccessDeniedException") {
|
|
99
|
+
const caller = /User: (arn:[^\s]+)/.exec(message)?.[1] ?? null;
|
|
100
|
+
return new LocalError(`${caller ?? "This AWS identity"} may not use KMS key ${signer.key_arn}.`, context, {
|
|
101
|
+
code: "KMS_ACCESS_DENIED",
|
|
102
|
+
details: { key_arn: signer.key_arn, caller_arn: caller },
|
|
103
|
+
next_actions: [{
|
|
104
|
+
type: "authenticate",
|
|
105
|
+
...(signer.aws_profile ? { command: `aws sso login --profile ${signer.aws_profile}` } : {}),
|
|
106
|
+
why: "Sign in as the identity the key's policy names (for a seller key, that person's SellerSigner session).",
|
|
107
|
+
}],
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const credentials = /CredentialsProviderError|ExpiredToken|UnrecognizedClient|InvalidSignature|TokenProviderError|SSO/i.test(name) ||
|
|
111
|
+
/token (?:has )?expired|sso session|could not load credentials|unable to load credentials|security token included in the request is expired/i.test(message);
|
|
112
|
+
return new LocalError(credentials
|
|
113
|
+
? `The AWS session for KMS key ${signer.key_arn} is missing or expired.`
|
|
114
|
+
: `KMS key ${signer.key_arn} could not be reached (${name || "error"}).`, context, {
|
|
115
|
+
code: "KMS_SIGNER_UNAVAILABLE",
|
|
116
|
+
details: { key_arn: signer.key_arn, region: signer.region, aws_error: name || null },
|
|
117
|
+
next_actions: credentials
|
|
118
|
+
? [{
|
|
119
|
+
type: "authenticate",
|
|
120
|
+
command: signer.aws_profile ? `aws sso login --profile ${signer.aws_profile}` : "aws sso login",
|
|
121
|
+
why: "Refresh the AWS session the key is reached through, then retry.",
|
|
122
|
+
}]
|
|
123
|
+
: [{ type: "retry", why: "Retry once KMS is reachable." }],
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const clients = new Map();
|
|
127
|
+
/** One KMS client per (region, profile) per process. */
|
|
128
|
+
function kmsClient(stack, signer) {
|
|
129
|
+
const key = `${signer.region}|${signer.aws_profile ?? ""}`;
|
|
130
|
+
let client = clients.get(key);
|
|
131
|
+
if (!client) {
|
|
132
|
+
client = new stack.KMSClient({ region: signer.region, ...(signer.aws_profile ? { profile: signer.aws_profile } : {}) });
|
|
133
|
+
clients.set(key, client);
|
|
134
|
+
}
|
|
135
|
+
return client;
|
|
136
|
+
}
|
|
137
|
+
/** A viem account that signs through `signer` as `address`. */
|
|
138
|
+
export async function kmsAccount(signer, address, opts = {}) {
|
|
139
|
+
let stack;
|
|
140
|
+
try {
|
|
141
|
+
stack = opts.stack ?? await loadKmsStack();
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
throw kmsError(err, signer, "loading the KMS signer");
|
|
145
|
+
}
|
|
146
|
+
const client = opts.client ?? kmsClient(stack, signer);
|
|
147
|
+
const { viem } = stack;
|
|
148
|
+
const signHash = async (hash) => {
|
|
149
|
+
let der;
|
|
150
|
+
try {
|
|
151
|
+
const out = await client.send(new stack.SignCommand({
|
|
152
|
+
KeyId: signer.key_arn,
|
|
153
|
+
Message: viem.hexToBytes(hash),
|
|
154
|
+
MessageType: "DIGEST",
|
|
155
|
+
SigningAlgorithm: "ECDSA_SHA_256",
|
|
156
|
+
}));
|
|
157
|
+
if (!out.Signature)
|
|
158
|
+
throw malformed("KMS returned no signature");
|
|
159
|
+
der = out.Signature;
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
throw kmsError(err, signer, "signing with a KMS wallet");
|
|
163
|
+
}
|
|
164
|
+
return derToEthereumSignature(viem, der, hash, address);
|
|
165
|
+
};
|
|
166
|
+
const account = stack.toAccount({
|
|
167
|
+
address: viem.getAddress(address),
|
|
168
|
+
async sign({ hash }) {
|
|
169
|
+
return signHash(hash);
|
|
170
|
+
},
|
|
171
|
+
async signMessage({ message }) {
|
|
172
|
+
return signHash(viem.hashMessage(message));
|
|
173
|
+
},
|
|
174
|
+
async signTypedData(typedData) {
|
|
175
|
+
return signHash(viem.hashTypedData(typedData));
|
|
176
|
+
},
|
|
177
|
+
async signTransaction(transaction, options) {
|
|
178
|
+
const serializer = (options?.serializer ?? viem.serializeTransaction);
|
|
179
|
+
// As viem's own local account does: an EIP-4844 transaction is signed without its sidecars.
|
|
180
|
+
const signable = transaction.type === "eip4844"
|
|
181
|
+
? { ...transaction, sidecars: false }
|
|
182
|
+
: transaction;
|
|
183
|
+
const signature = await signHash(viem.keccak256(await serializer(signable)));
|
|
184
|
+
return await serializer(transaction, viem.parseSignature(signature));
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
return account;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Read a KMS key's public key and metadata (read-only: `GetPublicKey` only)
|
|
191
|
+
* and derive its address; `KMS_KEY_UNSUITABLE` unless it is a secp256k1
|
|
192
|
+
* signing key.
|
|
193
|
+
*/
|
|
194
|
+
export async function adoptKmsKey(signer, opts = {}) {
|
|
195
|
+
let stack;
|
|
196
|
+
try {
|
|
197
|
+
stack = opts.stack ?? await loadKmsStack();
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
throw kmsError(err, signer, "importing a KMS wallet");
|
|
201
|
+
}
|
|
202
|
+
const client = opts.client ?? kmsClient(stack, signer);
|
|
203
|
+
let out;
|
|
204
|
+
try {
|
|
205
|
+
out = await client.send(new stack.GetPublicKeyCommand({ KeyId: signer.key_arn }));
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
throw kmsError(err, signer, "importing a KMS wallet");
|
|
209
|
+
}
|
|
210
|
+
if (out.KeySpec !== "ECC_SECG_P256K1" || out.KeyUsage !== "SIGN_VERIFY" || !out.PublicKey) {
|
|
211
|
+
throw new LocalError(`KMS key ${signer.key_arn} is ${out.KeySpec ?? "unknown"} / ${out.KeyUsage ?? "unknown"}; a wallet needs ECC_SECG_P256K1 / SIGN_VERIFY.`, "importing a KMS wallet", {
|
|
212
|
+
code: "KMS_KEY_UNSUITABLE",
|
|
213
|
+
details: { key_arn: signer.key_arn, key_spec: out.KeySpec ?? null, key_usage: out.KeyUsage ?? null },
|
|
214
|
+
next_actions: [{ type: "edit_request", why: "Import an asymmetric secp256k1 signing key (ECC_SECG_P256K1, SIGN_VERIFY)." }],
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return { address: addressFromSpki(stack.viem, out.PublicKey), key_spec: out.KeySpec, key_usage: out.KeyUsage };
|
|
218
|
+
}
|
|
219
|
+
const SECP256K1_SPKI_PREFIX = "3056301006072a8648ce3d020106052b8104000a034200";
|
|
220
|
+
/** The EVM address of a secp256k1 SubjectPublicKeyInfo (what KMS GetPublicKey returns). */
|
|
221
|
+
export function addressFromSpki(viem, der) {
|
|
222
|
+
const hex = bytesToHex(der);
|
|
223
|
+
if (!hex.startsWith(SECP256K1_SPKI_PREFIX) || hex.length !== SECP256K1_SPKI_PREFIX.length + 130 || hex.slice(SECP256K1_SPKI_PREFIX.length, SECP256K1_SPKI_PREFIX.length + 2) !== "04") {
|
|
224
|
+
throw new LocalError("The KMS public key is not a secp256k1 SubjectPublicKeyInfo with an uncompressed point.", "importing a KMS wallet", {
|
|
225
|
+
code: "KMS_KEY_UNSUITABLE",
|
|
226
|
+
next_actions: [{ type: "edit_request", why: "Import an asymmetric secp256k1 signing key (ECC_SECG_P256K1, SIGN_VERIFY)." }],
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
const hash = viem.keccak256(`0x${hex.slice(SECP256K1_SPKI_PREFIX.length + 2)}`);
|
|
230
|
+
return viem.getAddress(`0x${hash.slice(-40)}`);
|
|
231
|
+
}
|
|
232
|
+
/** Test seam: forget cached clients. */
|
|
233
|
+
export function resetKmsClientsForTests() {
|
|
234
|
+
clients.clear();
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=kms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kms.js","sourceRoot":"","sources":["../../../src/node/signers/kms.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `r.wallets.send` (spec `wallet-signers`, "Wallets Send USDC From Themselves
|
|
3
|
+
* Or From An Owned Smart Account"; `mpp-tempo-client-surface`, "Sending
|
|
4
|
+
* pathUSD On Tempo"). Moves a stablecoin from the selected wallet, which may
|
|
5
|
+
* be key-backed or KMS-backed:
|
|
6
|
+
*
|
|
7
|
+
* - `base` / `base-sepolia`: USDC, from the wallet itself, or `from` a
|
|
8
|
+
* CoinbaseSmartWallet the wallet owns (one transaction from the wallet
|
|
9
|
+
* calling the smart account's `execute`); gas in ETH.
|
|
10
|
+
* - `tempo` / `tempo-moderato`: pathUSD from the wallet itself; Tempo has no
|
|
11
|
+
* gas token, so the fee is paid in pathUSD too.
|
|
12
|
+
*
|
|
13
|
+
* Without `confirm: true` it checks everything and returns a preview without
|
|
14
|
+
* signing. A send reports success only once the transaction is mined
|
|
15
|
+
* successfully; a revert is a failure carrying its hash.
|
|
16
|
+
*/
|
|
17
|
+
import type { LocalAccount, Transport } from "viem";
|
|
18
|
+
export type SendNetwork = "base" | "base-sepolia" | "tempo" | "tempo-moderato";
|
|
19
|
+
export declare const SEND_NETWORKS: readonly SendNetwork[];
|
|
20
|
+
export interface SendOptions {
|
|
21
|
+
/** Decimal amount of the network's stablecoin, at most 6 decimal places (e.g. "10", "0.5"). */
|
|
22
|
+
amount: string;
|
|
23
|
+
to: string;
|
|
24
|
+
/** A CoinbaseSmartWallet the wallet owns, to send from instead of the wallet itself (Base only). */
|
|
25
|
+
from?: string;
|
|
26
|
+
network?: SendNetwork;
|
|
27
|
+
/** Sign and send. Without it, the checks run and a preview is returned. */
|
|
28
|
+
confirm?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface SendPreview {
|
|
31
|
+
preview: true;
|
|
32
|
+
network: SendNetwork;
|
|
33
|
+
asset: "USDC" | "pathUSD";
|
|
34
|
+
amount_usd_micros: number;
|
|
35
|
+
/** The address the money leaves. */
|
|
36
|
+
from: string;
|
|
37
|
+
to: string;
|
|
38
|
+
/** The address that signs and pays the fee. */
|
|
39
|
+
sender: string;
|
|
40
|
+
balance_usd_micros: number;
|
|
41
|
+
/** Gas units the send is estimated to use; null when the node could not estimate. */
|
|
42
|
+
estimated_gas: number | null;
|
|
43
|
+
}
|
|
44
|
+
export interface SendResult {
|
|
45
|
+
tx_hash: string;
|
|
46
|
+
from: string;
|
|
47
|
+
to: string;
|
|
48
|
+
amount_usd_micros: number;
|
|
49
|
+
network: SendNetwork;
|
|
50
|
+
asset: "USDC" | "pathUSD";
|
|
51
|
+
explorer_url: string;
|
|
52
|
+
}
|
|
53
|
+
/** "10.5" → 10_500_000n; refuses anything that is not a positive amount with at most 6 decimals. */
|
|
54
|
+
export declare function parseStablecoinAmount(amount: string): bigint;
|
|
55
|
+
/** The CLI command for these options, as the sandbox refusal names it. */
|
|
56
|
+
export declare function sendCommand(opts: Partial<SendOptions>): string;
|
|
57
|
+
export interface SendDeps {
|
|
58
|
+
/** Test seam: the RPC transport (default: the chain's public RPC). */
|
|
59
|
+
transport?: Transport;
|
|
60
|
+
}
|
|
61
|
+
export declare function sendFromWallet(account: LocalAccount, opts: SendOptions, deps?: SendDeps): Promise<SendPreview | SendResult>;
|
|
62
|
+
//# sourceMappingURL=wallets-send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallets-send.d.ts","sourceRoot":"","sources":["../../src/node/wallets-send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAuB,YAAY,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAIzE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,cAAc,GAAG,OAAO,GAAG,gBAAgB,CAAC;AAE/E,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAAwD,CAAC;AAmBzG,MAAM,WAAW,WAAW;IAC1B,+FAA+F;IAC/F,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,oGAAoG;IACpG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qFAAqF;IACrF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAQD,oGAAoG;AACpG,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQ5D;AA4BD,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,MAAM,CAU9D;AAED,MAAM,WAAW,QAAQ;IACvB,sEAAsE;IACtE,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,GAAE,QAAa,GAAG,OAAO,CAAC,WAAW,GAAG,UAAU,CAAC,CAuFrI"}
|