@atumlabs/payment-gateway-client 2.2.0 → 3.0.1
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/CHANGELOG.md +108 -0
- package/LICENSE +202 -83
- package/NOTICE +2 -0
- package/README.md +547 -46
- package/THIRD-PARTY-NOTICES.txt +7 -1
- package/dist/cli/approve-permit2.d.ts +1 -0
- package/dist/cli/approve-permit2.js +7325 -0
- package/dist/cli/payment-status.js +2307 -261
- package/dist/cli/quote-status.js +2305 -259
- package/dist/cli/request-quote.js +2333 -266
- package/dist/cli/send-payment.js +3079 -360
- package/dist/index.d.ts +926 -1701
- package/dist/index.js +3470 -492
- package/dist/sender-auth-verify-C-Q-zvAO.d.ts +2013 -0
- package/dist/signing.d.ts +223 -0
- package/dist/signing.js +7219 -0
- package/docs/idempotency.md +97 -40
- package/docs/signing.md +218 -0
- package/package.json +48 -14
- package/signing.d.ts +2 -0
- package/signing.js +11 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { P as PaymentRequest } from './sender-auth-verify-C-Q-zvAO.js';
|
|
2
|
+
export { A as AuthTerms, a as ParsedPermit, V as VerifiedSenderAuth, b as VerifyPaymentRequestExpectations, c as VerifyResult, v as verifyPaymentRequest } from './sender-auth-verify-C-Q-zvAO.js';
|
|
3
|
+
|
|
4
|
+
/** Options for {@link signDeclaration}. */
|
|
5
|
+
interface SignDeclarationOptions {
|
|
6
|
+
/** EVM chain id used in the verificationMethod DID. Defaults to 1. */
|
|
7
|
+
chainId?: number;
|
|
8
|
+
/**
|
|
9
|
+
* Override for proof.created, as an ISO-8601 UTC string. Defaults to now.
|
|
10
|
+
*
|
|
11
|
+
* The value is inside the signed payload, so pass it explicitly wherever a signature has to
|
|
12
|
+
* be reproducible — conformance fixtures and tests — and leave it unset in production.
|
|
13
|
+
*/
|
|
14
|
+
created?: string;
|
|
15
|
+
}
|
|
16
|
+
/** A W3C Data Integrity proof as it appears on a signed PaymentRequest. */
|
|
17
|
+
interface DeclarationProof {
|
|
18
|
+
type: string;
|
|
19
|
+
created: string;
|
|
20
|
+
verificationMethod: string;
|
|
21
|
+
proofPurpose: string;
|
|
22
|
+
jws?: string;
|
|
23
|
+
proofValue?: string;
|
|
24
|
+
}
|
|
25
|
+
/** A PaymentRequest with its `@context` and `proof` attached. */
|
|
26
|
+
type SignedDeclaration = PaymentRequest & {
|
|
27
|
+
'@context': string[];
|
|
28
|
+
proof: DeclarationProof;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The identity a verified document proof yields.
|
|
32
|
+
*
|
|
33
|
+
* Discriminated, and deliberately so. The two cases carry different weight, and flattening
|
|
34
|
+
* them into one shape is how a self-asserted key gets read as a proven one:
|
|
35
|
+
*
|
|
36
|
+
* - `recovered-secp256k1`: the address is recovered FROM the signature, so it is self-evident
|
|
37
|
+
* proof of which key signed.
|
|
38
|
+
* - `self-asserted-ed25519`: the public key is taken from the document's own
|
|
39
|
+
* verificationMethod. A successful verify proves the signature matches that key — NOT that
|
|
40
|
+
* the key belongs to anyone in particular. Bind it to a trusted source before relying on it.
|
|
41
|
+
*
|
|
42
|
+
* This mirrors the sealed Signer interface in the Go verifier, which exists for the same
|
|
43
|
+
* reason.
|
|
44
|
+
*/
|
|
45
|
+
type VerifiedDeclarationSigner = {
|
|
46
|
+
kind: 'recovered-secp256k1';
|
|
47
|
+
address: string;
|
|
48
|
+
did: string;
|
|
49
|
+
} | {
|
|
50
|
+
kind: 'self-asserted-ed25519';
|
|
51
|
+
publicKey: Uint8Array;
|
|
52
|
+
did: string;
|
|
53
|
+
};
|
|
54
|
+
/** What {@link verifyDeclaration} reports about a valid proof. */
|
|
55
|
+
interface VerifyDeclarationResult {
|
|
56
|
+
/** The verified identity. Discriminate on `kind` before reading it. */
|
|
57
|
+
signer: VerifiedDeclarationSigner;
|
|
58
|
+
/** The cryptosuite that produced the proof. */
|
|
59
|
+
cryptosuite: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Signs a 32-byte digest with the holder's secp256k1 key.
|
|
63
|
+
*
|
|
64
|
+
* This surface takes a signer rather than a private key, deliberately. A hex key forces raw key
|
|
65
|
+
* material into a JavaScript string that cannot be zeroized, is copied on assignment, and lands
|
|
66
|
+
* in heap snapshots and any log line that stringifies the surrounding object — and it locks out
|
|
67
|
+
* every custodian, since a holder whose key sits in a KMS, an HSM, or a provider like Turnkey
|
|
68
|
+
* has no key to hand over. Implement this over the provider's own digest-signing call, or use
|
|
69
|
+
* {@link signerFromEthersWallet} for a local key.
|
|
70
|
+
*
|
|
71
|
+
* Same shape as the SenderSigner seam this package already uses for the transfer authorization,
|
|
72
|
+
* and as the Go client's Secp256k1Signer.
|
|
73
|
+
*/
|
|
74
|
+
interface DeclarationSigner {
|
|
75
|
+
/** The 0x address this signer's key derives to; it becomes the did:pkh verificationMethod. */
|
|
76
|
+
getAddress(): Promise<string> | string;
|
|
77
|
+
/**
|
|
78
|
+
* Signs a 32-byte digest, returning 65 bytes of `r || s || v` with **v ∈ {0, 1}**.
|
|
79
|
+
*
|
|
80
|
+
* v is the raw recovery id. The alignment the W3C suite expects is applied once downstream,
|
|
81
|
+
* and a signature whose v is already 27 or 28 is REFUSED — applying it twice recovers a
|
|
82
|
+
* different address, i.e. a proof that verifies as somebody else.
|
|
83
|
+
*/
|
|
84
|
+
signDigest(digest: Uint8Array): Promise<Uint8Array> | Uint8Array;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Adapts an ethers `Wallet` to {@link DeclarationSigner}, for the local-key case.
|
|
88
|
+
*
|
|
89
|
+
* ethers owns the key material; this borrows only the digest-signing capability. It signs a RAW
|
|
90
|
+
* digest, not `signMessage`: the proof is over a canonicalized document hash, so the EIP-191
|
|
91
|
+
* prefix would produce a signature that does not verify as a Data Integrity proof.
|
|
92
|
+
*/
|
|
93
|
+
declare const signerFromEthersWallet: (wallet: unknown) => DeclarationSigner;
|
|
94
|
+
/**
|
|
95
|
+
* Signs a PaymentRequest document, returning a copy with `@context` and `proof` attached.
|
|
96
|
+
*
|
|
97
|
+
* The proof covers the URDNA2015-canonicalized document, so it is stable across key reordering
|
|
98
|
+
* and whitespace. Signing artifacts and the deprecated credential carriers are excluded from
|
|
99
|
+
* that hash by the signing library, and the verifier strips the identical set.
|
|
100
|
+
*
|
|
101
|
+
* One consequence worth knowing: canonicalization drops terms the declaration `@context` does
|
|
102
|
+
* not define, so a field this package's types do not model travels inside the signed document
|
|
103
|
+
* without being covered by the proof. Making a new field tamper-evident means adding it to the
|
|
104
|
+
* context, not just to the payload.
|
|
105
|
+
|
|
106
|
+
*/
|
|
107
|
+
declare function signDeclaration(request: PaymentRequest, signer: DeclarationSigner, options?: SignDeclarationOptions): Promise<SignedDeclaration>;
|
|
108
|
+
/**
|
|
109
|
+
* Verifies a signed PaymentRequest document and recovers its signer.
|
|
110
|
+
*
|
|
111
|
+
* THROWS if the proof is missing, malformed, does not verify, or — for a recovery-based
|
|
112
|
+
* suite — recovers a signer other than the one the document claims. Callers branch on the
|
|
113
|
+
* exception, not on a return value.
|
|
114
|
+
*
|
|
115
|
+
* This checks the document proof only. It says nothing about whether sender_auth authorizes a
|
|
116
|
+
* transfer, nor whether the originator's identity is established.
|
|
117
|
+
*/
|
|
118
|
+
declare function verifyDeclaration(signed: SignedDeclaration): Promise<VerifyDeclarationResult>;
|
|
119
|
+
/**
|
|
120
|
+
* Computes the canonical content hash of a PaymentRequest.
|
|
121
|
+
*
|
|
122
|
+
* This is the value an identity envelope binds as its `challenge`, so a caller assembling one
|
|
123
|
+
* needs the same hash the gateway will recompute.
|
|
124
|
+
*/
|
|
125
|
+
declare function computeRequestHash(request: PaymentRequest): Promise<string>;
|
|
126
|
+
|
|
127
|
+
declare const PAYMENT_REQUEST_ENVELOPE_CONTEXT_URL = "https://schemas.atum.network/declarations/PaymentRequestEnvelope/v1/context.jsonld";
|
|
128
|
+
declare const PAYMENT_REQUEST_ENVELOPE_TYPE = "PaymentRequestEnvelope";
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Signs a 32-byte digest with the holder's secp256k1 key.
|
|
132
|
+
*
|
|
133
|
+
* Takes a signer, never a private key, so a holder whose key sits in a KMS, an HSM, or a
|
|
134
|
+
* custodial provider can sign without it entering this process. `signerFromEthersWallet` covers
|
|
135
|
+
* a local key.
|
|
136
|
+
*
|
|
137
|
+
* Returns 65 bytes of `r || s || v` with **v ∈ {0, 1}**. A signature whose v is already 27 or
|
|
138
|
+
* 28 is refused: applying the alignment twice recovers a different holder.
|
|
139
|
+
*/
|
|
140
|
+
interface EnvelopeSigner {
|
|
141
|
+
signDigest(digest: Uint8Array): Promise<Uint8Array> | Uint8Array;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* A holder-signed PaymentRequestEnvelope.
|
|
145
|
+
*
|
|
146
|
+
* Typed rather than returned as `unknown`: a caller that has to cast cannot be told by the
|
|
147
|
+
* compiler when a field it reads stops existing, and the fields below are the ones the gateway
|
|
148
|
+
* checks — so getting them wrong is a rejected payment, not a type error at the call site.
|
|
149
|
+
*/
|
|
150
|
+
interface SignedPaymentRequestEnvelope {
|
|
151
|
+
'@context': string[];
|
|
152
|
+
type: string[];
|
|
153
|
+
holder: string;
|
|
154
|
+
verifiableCredential: unknown[];
|
|
155
|
+
proof: {
|
|
156
|
+
type: string;
|
|
157
|
+
created: string;
|
|
158
|
+
verificationMethod: string;
|
|
159
|
+
proofPurpose: string;
|
|
160
|
+
/** Binds the envelope to one request; the gateway recomputes it. */
|
|
161
|
+
challenge: string;
|
|
162
|
+
/** Binds the envelope to one environment. */
|
|
163
|
+
domain: string;
|
|
164
|
+
/** Present for secp256k1 proofs. */
|
|
165
|
+
jws?: string;
|
|
166
|
+
/** Present for ed25519 proofs. */
|
|
167
|
+
proofValue?: string;
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/** Inputs to {@link buildEnvelope}. Every field is required unless noted. */
|
|
171
|
+
interface BuildEnvelopeOptions {
|
|
172
|
+
/**
|
|
173
|
+
* The originator's issuer-signed credentials, each a fully-formed W3C VC with its own
|
|
174
|
+
* `@context` and `proof`.
|
|
175
|
+
*
|
|
176
|
+
* MUST be non-empty: the envelope schema requires at least one and the verifier rejects an
|
|
177
|
+
* empty bag. An originator that holds no credential about itself cannot build one yet.
|
|
178
|
+
*/
|
|
179
|
+
holderVCs: unknown[];
|
|
180
|
+
/** Signs the holder proof. See {@link EnvelopeSigner}. */
|
|
181
|
+
signer: EnvelopeSigner;
|
|
182
|
+
/** The holder's did:pkh identifier, e.g. `did:pkh:eip155:1:0xabc…`. */
|
|
183
|
+
holder: string;
|
|
184
|
+
/** The DID URL naming the holder's signing key, usually `holder + '#blockchainAccountId'`. */
|
|
185
|
+
verificationMethod: string;
|
|
186
|
+
/**
|
|
187
|
+
* The cross-request replay binding: the payment's `request_hash`, which the gateway recomputes over the inner request. Use `computeRequestHash` to derive it.
|
|
188
|
+
*/
|
|
189
|
+
challenge: string;
|
|
190
|
+
/**
|
|
191
|
+
* The cross-environment replay binding: the network-wide, env-suffixed did:web identifier
|
|
192
|
+
* (e.g. `did:web:devnet.atum.network`). NOT service-bound — the envelope has several
|
|
193
|
+
* consumers.
|
|
194
|
+
*/
|
|
195
|
+
domain: string;
|
|
196
|
+
/**
|
|
197
|
+
* Anchors `proof.created`, as an ISO-8601 UTC string. Defaults to now.
|
|
198
|
+
*
|
|
199
|
+
* It is inside the signed payload, so pass it explicitly wherever a signature must be
|
|
200
|
+
* reproducible.
|
|
201
|
+
*/
|
|
202
|
+
created?: string;
|
|
203
|
+
}
|
|
204
|
+
/** Builds the did:pkh identifier for a wallet account on a CAIP-2 chain. */
|
|
205
|
+
declare function didForAccount(chainId: string, account: string): string;
|
|
206
|
+
/** Builds the DID URL naming a wallet account's signing key. */
|
|
207
|
+
declare function verificationMethodForAccount(chainId: string, account: string): string;
|
|
208
|
+
/**
|
|
209
|
+
* Wraps the originator's credentials in a holder-signed PaymentRequestEnvelope and returns the
|
|
210
|
+
* envelope JSON.
|
|
211
|
+
*
|
|
212
|
+
* It does NOT sign the inner PaymentRequest. That is a separate artifact — see
|
|
213
|
+
* `signDeclaration` — and the verifier checks the two independently, asserting the inner signer
|
|
214
|
+
* is this envelope's holder. Sign both with the same key, or the gateway rejects the pair.
|
|
215
|
+
*/
|
|
216
|
+
declare function buildEnvelope(options: BuildEnvelopeOptions): Promise<SignedPaymentRequestEnvelope>;
|
|
217
|
+
/**
|
|
218
|
+
* Convenience over {@link buildEnvelope} for the common case: derive the holder DID and
|
|
219
|
+
* verification method from the wallet's chain and address.
|
|
220
|
+
*/
|
|
221
|
+
declare function buildEnvelopeForAccount(chainId: string, account: string, options: Omit<BuildEnvelopeOptions, 'holder' | 'verificationMethod'>): Promise<SignedPaymentRequestEnvelope>;
|
|
222
|
+
|
|
223
|
+
export { type BuildEnvelopeOptions, type DeclarationSigner, type EnvelopeSigner, PAYMENT_REQUEST_ENVELOPE_CONTEXT_URL, PAYMENT_REQUEST_ENVELOPE_TYPE, type SignDeclarationOptions, type SignedDeclaration, type SignedPaymentRequestEnvelope, type VerifiedDeclarationSigner, type VerifyDeclarationResult, buildEnvelope, buildEnvelopeForAccount, computeRequestHash, didForAccount, signDeclaration, signerFromEthersWallet, verificationMethodForAccount, verifyDeclaration };
|