passkey-kit 0.12.0 → 0.13.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/README.md +399 -227
- package/{types → dist}/base.d.ts +2 -1
- package/dist/base.d.ts.map +1 -0
- package/{src/base.ts → dist/base.js} +8 -10
- package/dist/base.js.map +1 -0
- package/dist/base64url.d.ts +18 -0
- package/dist/base64url.d.ts.map +1 -0
- package/dist/base64url.js +18 -0
- package/dist/base64url.js.map +1 -0
- package/dist/constants.d.ts +87 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +111 -0
- package/dist/constants.js.map +1 -0
- package/dist/contract-errors.d.ts +69 -0
- package/dist/contract-errors.d.ts.map +1 -0
- package/dist/contract-errors.js +129 -0
- package/dist/contract-errors.js.map +1 -0
- package/dist/errors.d.ts +163 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +244 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +94 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +92 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/codec.d.ts +18 -0
- package/dist/indexer/codec.d.ts.map +1 -0
- package/dist/indexer/codec.js +32 -0
- package/dist/indexer/codec.js.map +1 -0
- package/dist/indexer/index.d.ts +25 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +34 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/mercury.d.ts +88 -0
- package/dist/indexer/mercury.d.ts.map +1 -0
- package/dist/indexer/mercury.js +237 -0
- package/dist/indexer/mercury.js.map +1 -0
- package/dist/indexer/stellar-indexer.d.ts +115 -0
- package/dist/indexer/stellar-indexer.d.ts.map +1 -0
- package/dist/indexer/stellar-indexer.js +279 -0
- package/dist/indexer/stellar-indexer.js.map +1 -0
- package/dist/indexer/types.d.ts +73 -0
- package/dist/indexer/types.d.ts.map +1 -0
- package/dist/indexer/types.js +9 -0
- package/dist/indexer/types.js.map +1 -0
- package/dist/kit/auth-payload.d.ts +89 -0
- package/dist/kit/auth-payload.d.ts.map +1 -0
- package/dist/kit/auth-payload.js +203 -0
- package/dist/kit/auth-payload.js.map +1 -0
- package/dist/kit/deploy-ops.d.ts +45 -0
- package/dist/kit/deploy-ops.d.ts.map +1 -0
- package/dist/kit/deploy-ops.js +69 -0
- package/dist/kit/deploy-ops.js.map +1 -0
- package/dist/kit/tx-ops.d.ts +92 -0
- package/dist/kit/tx-ops.d.ts.map +1 -0
- package/dist/kit/tx-ops.js +113 -0
- package/dist/kit/tx-ops.js.map +1 -0
- package/dist/kit/wallet-ops.d.ts +59 -0
- package/dist/kit/wallet-ops.d.ts.map +1 -0
- package/dist/kit/wallet-ops.js +122 -0
- package/dist/kit/wallet-ops.js.map +1 -0
- package/dist/kit/webauthn-ops.d.ts +55 -0
- package/dist/kit/webauthn-ops.d.ts.map +1 -0
- package/dist/kit/webauthn-ops.js +79 -0
- package/dist/kit/webauthn-ops.js.map +1 -0
- package/dist/kit.d.ts +128 -0
- package/dist/kit.d.ts.map +1 -0
- package/dist/kit.js +276 -0
- package/dist/kit.js.map +1 -0
- package/dist/managers/credential-manager.d.ts +39 -0
- package/dist/managers/credential-manager.d.ts.map +1 -0
- package/dist/managers/credential-manager.js +47 -0
- package/dist/managers/credential-manager.js.map +1 -0
- package/dist/managers/index.d.ts +7 -0
- package/dist/managers/index.d.ts.map +1 -0
- package/dist/managers/index.js +7 -0
- package/dist/managers/index.js.map +1 -0
- package/dist/managers/signer-manager.d.ts +51 -0
- package/dist/managers/signer-manager.d.ts.map +1 -0
- package/dist/managers/signer-manager.js +92 -0
- package/dist/managers/signer-manager.js.map +1 -0
- package/dist/managers/submission-manager.d.ts +52 -0
- package/dist/managers/submission-manager.d.ts.map +1 -0
- package/dist/managers/submission-manager.js +77 -0
- package/dist/managers/submission-manager.js.map +1 -0
- package/dist/relayer.d.ts +61 -0
- package/dist/relayer.d.ts.map +1 -0
- package/dist/relayer.js +119 -0
- package/dist/relayer.js.map +1 -0
- package/dist/rpc-data.d.ts +35 -0
- package/dist/rpc-data.d.ts.map +1 -0
- package/dist/rpc-data.js +49 -0
- package/dist/rpc-data.js.map +1 -0
- package/dist/sac.d.ts +31 -0
- package/dist/sac.d.ts.map +1 -0
- package/dist/sac.js +47 -0
- package/dist/sac.js.map +1 -0
- package/dist/server.d.ts +79 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +152 -0
- package/dist/server.js.map +1 -0
- package/dist/signers.d.ts +83 -0
- package/dist/signers.d.ts.map +1 -0
- package/dist/signers.js +124 -0
- package/dist/signers.js.map +1 -0
- package/dist/storage/index.d.ts +13 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +12 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/indexeddb.d.ts +26 -0
- package/dist/storage/indexeddb.d.ts.map +1 -0
- package/dist/storage/indexeddb.js +100 -0
- package/dist/storage/indexeddb.js.map +1 -0
- package/dist/storage/localStorage.d.ts +22 -0
- package/dist/storage/localStorage.d.ts.map +1 -0
- package/dist/storage/localStorage.js +86 -0
- package/dist/storage/localStorage.js.map +1 -0
- package/dist/storage/memory.d.ts +18 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +41 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/types.d.ts +136 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +39 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +52 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +153 -0
- package/dist/utils.js.map +1 -0
- package/dist/validation.d.ts +40 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +73 -0
- package/dist/validation.js.map +1 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +9 -0
- package/dist/version.js.map +1 -0
- package/package.json +48 -20
- package/.claude/settings.local.json +0 -20
- package/.cursorrules +0 -170
- package/.gitattributes +0 -2
- package/.github/workflows/release.yml +0 -21
- package/.vscode/settings.json +0 -6
- package/PROPOSAL.md +0 -397
- package/cheatsheet.txt +0 -18
- package/clone-js-sdk.sh +0 -21
- package/packages/passkey-kit-sdk/README.md +0 -54
- package/packages/passkey-kit-sdk/package.json +0 -18
- package/packages/passkey-kit-sdk/src/index.ts +0 -171
- package/packages/passkey-kit-sdk/tsconfig.json +0 -98
- package/packages/passkey-kit-sdk/types/index.d.ts +0 -190
- package/packages/sac-sdk/README.md +0 -54
- package/packages/sac-sdk/package.json +0 -18
- package/packages/sac-sdk/src/index.ts +0 -586
- package/packages/sac-sdk/tsconfig.json +0 -98
- package/packages/sac-sdk/types/index.d.ts +0 -532
- package/pnpm-workspace.yaml +0 -2
- package/src/index.ts +0 -5
- package/src/kit.ts +0 -698
- package/src/sac.ts +0 -29
- package/src/server.ts +0 -179
- package/src/types.ts +0 -32
- package/tsconfig.json +0 -28
- package/types/index.d.ts +0 -5
- package/types/kit.d.ts +0 -89
- package/types/sac.d.ts +0 -13
- package/types/server.d.ts +0 -29
- package/types/types.d.ts +0 -22
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Submission manager: builds and signs the deploy transaction with the fee-
|
|
3
|
+
* paying deployer keypair, derives deterministic wallet addresses, and drives
|
|
4
|
+
* the footprint-restore flow.
|
|
5
|
+
*
|
|
6
|
+
* Network submission itself is the server's job (`PasskeyServer` / relayer); this
|
|
7
|
+
* manager owns the deployer keypair and the fee-payer signature that make a
|
|
8
|
+
* deploy transaction submittable.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import { TransactionBuilder } from "@stellar/stellar-sdk";
|
|
13
|
+
import { buildDeployTransaction as buildDeployTransactionOp, deriveWalletAddress as deriveWalletAddressOp, } from "../kit/deploy-ops.js";
|
|
14
|
+
import { restoreFootprint as restoreFootprintOp, } from "../kit/tx-ops.js";
|
|
15
|
+
export class SubmissionManager {
|
|
16
|
+
deps;
|
|
17
|
+
constructor(deps) {
|
|
18
|
+
this.deps = deps;
|
|
19
|
+
}
|
|
20
|
+
/** The deployer's `G…` public key (fee source + derivation deployer). */
|
|
21
|
+
get deployerPublicKey() {
|
|
22
|
+
return this.deps.deployerKeypair.publicKey();
|
|
23
|
+
}
|
|
24
|
+
/** Deterministically derive the wallet address for a passkey credential. */
|
|
25
|
+
deriveWalletAddress(keyId) {
|
|
26
|
+
return deriveWalletAddressOp({
|
|
27
|
+
networkPassphrase: this.deps.networkPassphrase,
|
|
28
|
+
deployerPublicKey: this.deployerPublicKey,
|
|
29
|
+
}, keyId);
|
|
30
|
+
}
|
|
31
|
+
/** Build the wallet deploy transaction (initial Secp256r1 signer). */
|
|
32
|
+
buildDeployTransaction(keyId, publicKey) {
|
|
33
|
+
return buildDeployTransactionOp({
|
|
34
|
+
rpcUrl: this.deps.rpcUrl,
|
|
35
|
+
networkPassphrase: this.deps.networkPassphrase,
|
|
36
|
+
walletWasmHash: this.deps.walletWasmHash,
|
|
37
|
+
deployerPublicKey: this.deployerPublicKey,
|
|
38
|
+
timeoutInSeconds: this.deps.timeoutInSeconds,
|
|
39
|
+
}, keyId, publicKey);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Sign a deploy transaction with the deployer keypair (the fee source) and
|
|
43
|
+
* return the signed transaction XDR.
|
|
44
|
+
*
|
|
45
|
+
* The deploy carries source-account auth, so it is submitted through the
|
|
46
|
+
* relayer's fee-bump (`{ xdr }`) path. A fee-bumped Soroban inner transaction
|
|
47
|
+
* must have `fee == resourceFee` — the fee-bump supplies the inclusion fee —
|
|
48
|
+
* or the relayer rejects it with a fee mismatch ("Transaction fee must be
|
|
49
|
+
* equal to the resource fee"). The assembled fee is `inclusion + resource`,
|
|
50
|
+
* so pin it to the resource fee BEFORE the deployer signs (the signature
|
|
51
|
+
* commits to the fee). `TransactionBuilder.cloneFrom` drops
|
|
52
|
+
* `SorobanTransactionData` (→ txMalformed), so set the fee field surgically on
|
|
53
|
+
* the envelope and rebuild.
|
|
54
|
+
*/
|
|
55
|
+
async signDeploy(tx) {
|
|
56
|
+
if (!tx.built) {
|
|
57
|
+
throw new Error("deploy transaction has not been built/simulated");
|
|
58
|
+
}
|
|
59
|
+
const envelope = tx.built.toEnvelope();
|
|
60
|
+
const inner = envelope.v1().tx();
|
|
61
|
+
const resourceFee = inner.ext().sorobanData().resourceFee().toString();
|
|
62
|
+
inner.fee(Number(resourceFee));
|
|
63
|
+
const feeAdjusted = TransactionBuilder.fromXDR(envelope.toXDR("base64"), this.deps.networkPassphrase);
|
|
64
|
+
feeAdjusted.sign(this.deps.deployerKeypair);
|
|
65
|
+
return feeAdjusted.toXDR();
|
|
66
|
+
}
|
|
67
|
+
/** Restore an archived footprint reported by simulation. */
|
|
68
|
+
restoreFootprint(restorePreamble) {
|
|
69
|
+
return restoreFootprintOp({
|
|
70
|
+
rpc: this.deps.rpc,
|
|
71
|
+
networkPassphrase: this.deps.networkPassphrase,
|
|
72
|
+
deployerKeypair: this.deps.deployerKeypair,
|
|
73
|
+
timeoutInSeconds: this.deps.timeoutInSeconds,
|
|
74
|
+
}, restorePreamble);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=submission-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submission-manager.js","sourceRoot":"","sources":["../../src/managers/submission-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAK1D,OAAO,EACL,sBAAsB,IAAI,wBAAwB,EAClD,mBAAmB,IAAI,qBAAqB,GAC7C,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,gBAAgB,IAAI,kBAAkB,GAEvC,MAAM,kBAAkB,CAAC;AAW1B,MAAM,OAAO,iBAAiB;IACC;IAA7B,YAA6B,IAA2B;QAA3B,SAAI,GAAJ,IAAI,CAAuB;IAAG,CAAC;IAE5D,yEAAyE;IACzE,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC;IAC/C,CAAC;IAED,4EAA4E;IAC5E,mBAAmB,CAAC,KAAa;QAC/B,OAAO,qBAAqB,CAC1B;YACE,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAC9C,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;SAC1C,EACD,KAAK,CACN,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,sBAAsB,CACpB,KAAa,EACb,SAAqB;QAErB,OAAO,wBAAwB,CAC7B;YACE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;YACxB,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAC9C,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc;YACxC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB;SAC7C,EACD,KAAK,EACL,SAAS,CACV,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,UAAU,CAAC,EAAuC;QACtD,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC;QACvE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;QAE/B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAC5C,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EACxB,IAAI,CAAC,IAAI,CAAC,iBAAiB,CACb,CAAC;QACjB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5C,OAAO,WAAW,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,4DAA4D;IAC5D,gBAAgB,CAAC,eAAgC;QAC/C,OAAO,kBAAkB,CACvB;YACE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG;YAClB,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAC9C,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe;YAC1C,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB;SAC7C,EACD,eAAe,CAChB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side relayer client.
|
|
3
|
+
*
|
|
4
|
+
* A thin, typed wrapper over the OpenZeppelin Channels client
|
|
5
|
+
* (`@openzeppelin/relayer-plugin-channels` ^0.20) for fee-sponsored submission.
|
|
6
|
+
* It holds the relayer API key, so it MUST run server-side only (it is reached
|
|
7
|
+
* through `PasskeyServer`, exported from the `passkey-kit/server` subpath).
|
|
8
|
+
*
|
|
9
|
+
* Two submission modes:
|
|
10
|
+
* - {@link RelayerClient.send} — `{ func, auth }` for invokeHostFunction flows
|
|
11
|
+
* (the preferred Soroban path; the relayer builds the envelope + pays fees).
|
|
12
|
+
* - {@link RelayerClient.sendTransaction} — `{ xdr }` for a signed envelope
|
|
13
|
+
* (e.g. a deploy transaction that needs source-account auth + a fee bump).
|
|
14
|
+
*
|
|
15
|
+
* Every method returns a discriminated {@link TransactionResult} and NEVER
|
|
16
|
+
* throws for expected relayer/on-chain failures — a `PluginClientError` is
|
|
17
|
+
* mapped to a typed {@link RelayerError} (or a {@link ContractError} when a
|
|
18
|
+
* contract code can be decoded from its details).
|
|
19
|
+
*
|
|
20
|
+
* @packageDocumentation
|
|
21
|
+
*/
|
|
22
|
+
import type { TransactionResult } from "./types.js";
|
|
23
|
+
/** Configuration for a {@link RelayerClient}. */
|
|
24
|
+
export interface RelayerClientConfig {
|
|
25
|
+
/** Base URL of the Channels relayer service. */
|
|
26
|
+
baseUrl: string;
|
|
27
|
+
/** API key for the relayer service (server-side secret). */
|
|
28
|
+
apiKey: string;
|
|
29
|
+
/** Optional admin secret for management operations. */
|
|
30
|
+
adminSecret?: string;
|
|
31
|
+
/** Request timeout in ms (default {@link DEFAULT_RELAYER_TIMEOUT_MS}). */
|
|
32
|
+
timeout?: number;
|
|
33
|
+
}
|
|
34
|
+
/** Per-submission relayer options. */
|
|
35
|
+
export interface RelayerSubmitOptions {
|
|
36
|
+
/** Return immediately after submission; poll {@link RelayerClient.getTransaction}. */
|
|
37
|
+
skipWait?: boolean;
|
|
38
|
+
/** Alternative fund-relayer id for the fee bump (must be allow-listed). */
|
|
39
|
+
fundRelayerId?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare class RelayerClient {
|
|
42
|
+
private readonly channels;
|
|
43
|
+
constructor(config: RelayerClientConfig);
|
|
44
|
+
/**
|
|
45
|
+
* Submit an invokeHostFunction via `{ func, auth }` (the preferred Soroban
|
|
46
|
+
* path). The relayer builds the transaction envelope with a channel account
|
|
47
|
+
* and pays the fees.
|
|
48
|
+
*/
|
|
49
|
+
send(func: string, auth: string[], options?: RelayerSubmitOptions): Promise<TransactionResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Submit a signed transaction envelope via `{ xdr }` for a fee bump (preserves
|
|
52
|
+
* the inner signature; use for deploys / source-account-auth transactions).
|
|
53
|
+
*/
|
|
54
|
+
sendTransaction(xdr: string, options?: RelayerSubmitOptions): Promise<TransactionResult>;
|
|
55
|
+
/** Poll a previously-submitted (`skipWait`) transaction by its relayer id. */
|
|
56
|
+
getTransaction(transactionId: string): Promise<TransactionResult>;
|
|
57
|
+
private run;
|
|
58
|
+
private toResult;
|
|
59
|
+
private mapError;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=relayer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relayer.d.ts","sourceRoot":"","sources":["../src/relayer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,OAAO,KAAK,EAAE,iBAAiB,EAAsB,MAAM,YAAY,CAAC;AAQxE,iDAAiD;AACjD,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,sCAAsC;AACtC,MAAM,WAAW,oBAAoB;IACnC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAaD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;gBAE9B,MAAM,EAAE,mBAAmB;IAevC;;;;OAIG;IACG,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAW7B;;;OAGG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAU7B,8EAA8E;IACxE,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAIzD,GAAG;IAUjB,OAAO,CAAC,QAAQ;IAqChB,OAAO,CAAC,QAAQ;CAiCjB"}
|
package/dist/relayer.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side relayer client.
|
|
3
|
+
*
|
|
4
|
+
* A thin, typed wrapper over the OpenZeppelin Channels client
|
|
5
|
+
* (`@openzeppelin/relayer-plugin-channels` ^0.20) for fee-sponsored submission.
|
|
6
|
+
* It holds the relayer API key, so it MUST run server-side only (it is reached
|
|
7
|
+
* through `PasskeyServer`, exported from the `passkey-kit/server` subpath).
|
|
8
|
+
*
|
|
9
|
+
* Two submission modes:
|
|
10
|
+
* - {@link RelayerClient.send} — `{ func, auth }` for invokeHostFunction flows
|
|
11
|
+
* (the preferred Soroban path; the relayer builds the envelope + pays fees).
|
|
12
|
+
* - {@link RelayerClient.sendTransaction} — `{ xdr }` for a signed envelope
|
|
13
|
+
* (e.g. a deploy transaction that needs source-account auth + a fee bump).
|
|
14
|
+
*
|
|
15
|
+
* Every method returns a discriminated {@link TransactionResult} and NEVER
|
|
16
|
+
* throws for expected relayer/on-chain failures — a `PluginClientError` is
|
|
17
|
+
* mapped to a typed {@link RelayerError} (or a {@link ContractError} when a
|
|
18
|
+
* contract code can be decoded from its details).
|
|
19
|
+
*
|
|
20
|
+
* @packageDocumentation
|
|
21
|
+
*/
|
|
22
|
+
import { ChannelsClient, PluginClientError, } from "@openzeppelin/relayer-plugin-channels";
|
|
23
|
+
import { RelayerError, PasskeyKitErrorCode } from "./errors.js";
|
|
24
|
+
import { decodeContractError, failedTransaction, } from "./contract-errors.js";
|
|
25
|
+
import { DEFAULT_RELAYER_TIMEOUT_MS } from "./constants.js";
|
|
26
|
+
/**
|
|
27
|
+
* Terminal-success statuses (ALLOWLIST). Only a status that positively confirms
|
|
28
|
+
* on-chain inclusion counts as success — anything else is failure or still
|
|
29
|
+
* pending. An allowlist (not a failure denylist) is deliberate: an unrecognized
|
|
30
|
+
* or non-terminal status must never be mistaken for a confirmed transaction.
|
|
31
|
+
*/
|
|
32
|
+
const SUCCESS_STATUS = /confirm|success/i;
|
|
33
|
+
/** Terminal-failure statuses. */
|
|
34
|
+
const FAILURE_STATUS = /fail|error|revert|reject/i;
|
|
35
|
+
export class RelayerClient {
|
|
36
|
+
channels;
|
|
37
|
+
constructor(config) {
|
|
38
|
+
if (!config.baseUrl || !config.apiKey) {
|
|
39
|
+
throw new RelayerError("RelayerClient requires both baseUrl and apiKey", PasskeyKitErrorCode.RELAYER_NOT_CONFIGURED);
|
|
40
|
+
}
|
|
41
|
+
this.channels = new ChannelsClient({
|
|
42
|
+
baseUrl: config.baseUrl,
|
|
43
|
+
apiKey: config.apiKey,
|
|
44
|
+
adminSecret: config.adminSecret,
|
|
45
|
+
timeout: config.timeout ?? DEFAULT_RELAYER_TIMEOUT_MS,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Submit an invokeHostFunction via `{ func, auth }` (the preferred Soroban
|
|
50
|
+
* path). The relayer builds the transaction envelope with a channel account
|
|
51
|
+
* and pays the fees.
|
|
52
|
+
*/
|
|
53
|
+
async send(func, auth, options) {
|
|
54
|
+
return this.run(() => this.channels.submitSorobanTransaction({
|
|
55
|
+
func,
|
|
56
|
+
auth,
|
|
57
|
+
skipWait: options?.skipWait,
|
|
58
|
+
fundRelayerId: options?.fundRelayerId,
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Submit a signed transaction envelope via `{ xdr }` for a fee bump (preserves
|
|
63
|
+
* the inner signature; use for deploys / source-account-auth transactions).
|
|
64
|
+
*/
|
|
65
|
+
async sendTransaction(xdr, options) {
|
|
66
|
+
return this.run(() => this.channels.submitTransaction({
|
|
67
|
+
xdr,
|
|
68
|
+
skipWait: options?.skipWait,
|
|
69
|
+
fundRelayerId: options?.fundRelayerId,
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
/** Poll a previously-submitted (`skipWait`) transaction by its relayer id. */
|
|
73
|
+
async getTransaction(transactionId) {
|
|
74
|
+
return this.run(() => this.channels.getTransaction({ transactionId }));
|
|
75
|
+
}
|
|
76
|
+
async run(fn) {
|
|
77
|
+
try {
|
|
78
|
+
return this.toResult(await fn());
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
return this.mapError(err);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
toResult(res) {
|
|
85
|
+
const status = res.status ?? "";
|
|
86
|
+
if (SUCCESS_STATUS.test(status)) {
|
|
87
|
+
return {
|
|
88
|
+
success: true,
|
|
89
|
+
hash: res.hash ?? "",
|
|
90
|
+
...(res.transactionId ? { transactionId: res.transactionId } : {}),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (FAILURE_STATUS.test(status)) {
|
|
94
|
+
return failedTransaction(new RelayerError(`Relayer reported status "${res.status}"`, PasskeyKitErrorCode.RELAYER_REQUEST_FAILED, { status: res.status, transactionId: res.transactionId }), res.hash ?? undefined);
|
|
95
|
+
}
|
|
96
|
+
// Neither terminal-success nor terminal-failure: the transaction is still
|
|
97
|
+
// pending (e.g. a `skipWait` submit not yet polled to confirmation). Surface
|
|
98
|
+
// it as a distinct, NON-success result carrying RELAYER_PENDING — never as
|
|
99
|
+
// `success: true` — so a poll loop keeps polling instead of treating an
|
|
100
|
+
// unconfirmed (or later-reverted) transaction as done.
|
|
101
|
+
return failedTransaction(new RelayerError(`Relayer status "${res.status ?? "unknown"}" is not terminal (pending)`, PasskeyKitErrorCode.RELAYER_PENDING, { status: res.status, transactionId: res.transactionId, pending: true }), res.hash ?? undefined);
|
|
102
|
+
}
|
|
103
|
+
mapError(err) {
|
|
104
|
+
// Prefer a decoded contract error when the relayer surfaced one.
|
|
105
|
+
const details = err instanceof PluginClientError
|
|
106
|
+
? err.errorDetails
|
|
107
|
+
: undefined;
|
|
108
|
+
const contractError = (err instanceof Error && decodeContractError(err.message)) ||
|
|
109
|
+
decodeContractError(details);
|
|
110
|
+
if (contractError) {
|
|
111
|
+
return failedTransaction(contractError);
|
|
112
|
+
}
|
|
113
|
+
if (err instanceof PluginClientError) {
|
|
114
|
+
return failedTransaction(new RelayerError(err.message, PasskeyKitErrorCode.RELAYER_REQUEST_FAILED, { category: err.category, details }, err));
|
|
115
|
+
}
|
|
116
|
+
return failedTransaction(new RelayerError(err instanceof Error ? err.message : String(err), PasskeyKitErrorCode.RELAYER_REQUEST_FAILED, undefined, err instanceof Error ? err : undefined));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=relayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relayer.js","sourceRoot":"","sources":["../src/relayer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct contract-data ledger reads that distinguish a genuine not-found from a
|
|
3
|
+
* transport failure.
|
|
4
|
+
*
|
|
5
|
+
* `Server.getContractData` collapses BOTH a real not-found AND any transport
|
|
6
|
+
* error (429/5xx/timeout, aborted fetch) into an identical `{ code: 404 }`
|
|
7
|
+
* throw, so a caller can't tell "the entry is gone" from "the RPC hiccuped".
|
|
8
|
+
* These helpers go one level lower: `getLedgerEntries` resolves with an empty
|
|
9
|
+
* `entries` array for a genuine not-found and only throws on an actual transport
|
|
10
|
+
* failure. That lets eviction detection and `getSigner`'s ownership check treat
|
|
11
|
+
* the two cases correctly instead of false-evicting live signers (audit H2) or
|
|
12
|
+
* reporting a valid passkey as "not a signer" on a flaky RPC.
|
|
13
|
+
*
|
|
14
|
+
* @packageDocumentation
|
|
15
|
+
*/
|
|
16
|
+
import { xdr } from "@stellar/stellar-sdk";
|
|
17
|
+
import { Durability, type Server } from "@stellar/stellar-sdk/rpc";
|
|
18
|
+
/** Build the contract-data `LedgerKey` for a (contract, key, durability) triple. */
|
|
19
|
+
export declare function contractDataLedgerKey(contractId: string, key: xdr.ScVal, durability: Durability): xdr.LedgerKey;
|
|
20
|
+
/**
|
|
21
|
+
* Read a contract-data entry's stored ScVal, or `null` when the entry genuinely
|
|
22
|
+
* does not exist in that durability.
|
|
23
|
+
*
|
|
24
|
+
* Transport errors are NOT swallowed — they propagate so a caller never mistakes
|
|
25
|
+
* a flaky RPC for an absent entry.
|
|
26
|
+
*/
|
|
27
|
+
export declare function readContractData(rpc: Server, contractId: string, key: xdr.ScVal, durability: Durability): Promise<xdr.ScVal | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Whether a contract-data entry exists in the given durability.
|
|
30
|
+
*
|
|
31
|
+
* Returns `false` only on a genuine not-found; a transport error throws (so
|
|
32
|
+
* callers conclude eviction exclusively from an authoritative not-found).
|
|
33
|
+
*/
|
|
34
|
+
export declare function contractDataExists(rpc: Server, contractId: string, key: xdr.ScVal, durability: Durability): Promise<boolean>;
|
|
35
|
+
//# sourceMappingURL=rpc-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-data.d.ts","sourceRoot":"","sources":["../src/rpc-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAW,GAAG,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEnE,oFAAoF;AACpF,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,GAAG,CAAC,KAAK,EACd,UAAU,EAAE,UAAU,GACrB,GAAG,CAAC,SAAS,CAWf;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,GAAG,CAAC,KAAK,EACd,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAM3B;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,GAAG,CAAC,KAAK,EACd,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,OAAO,CAAC,CAElB"}
|
package/dist/rpc-data.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct contract-data ledger reads that distinguish a genuine not-found from a
|
|
3
|
+
* transport failure.
|
|
4
|
+
*
|
|
5
|
+
* `Server.getContractData` collapses BOTH a real not-found AND any transport
|
|
6
|
+
* error (429/5xx/timeout, aborted fetch) into an identical `{ code: 404 }`
|
|
7
|
+
* throw, so a caller can't tell "the entry is gone" from "the RPC hiccuped".
|
|
8
|
+
* These helpers go one level lower: `getLedgerEntries` resolves with an empty
|
|
9
|
+
* `entries` array for a genuine not-found and only throws on an actual transport
|
|
10
|
+
* failure. That lets eviction detection and `getSigner`'s ownership check treat
|
|
11
|
+
* the two cases correctly instead of false-evicting live signers (audit H2) or
|
|
12
|
+
* reporting a valid passkey as "not a signer" on a flaky RPC.
|
|
13
|
+
*
|
|
14
|
+
* @packageDocumentation
|
|
15
|
+
*/
|
|
16
|
+
import { Address, xdr } from "@stellar/stellar-sdk";
|
|
17
|
+
import { Durability } from "@stellar/stellar-sdk/rpc";
|
|
18
|
+
/** Build the contract-data `LedgerKey` for a (contract, key, durability) triple. */
|
|
19
|
+
export function contractDataLedgerKey(contractId, key, durability) {
|
|
20
|
+
return xdr.LedgerKey.contractData(new xdr.LedgerKeyContractData({
|
|
21
|
+
contract: Address.fromString(contractId).toScAddress(),
|
|
22
|
+
key,
|
|
23
|
+
durability: durability === Durability.Temporary
|
|
24
|
+
? xdr.ContractDataDurability.temporary()
|
|
25
|
+
: xdr.ContractDataDurability.persistent(),
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Read a contract-data entry's stored ScVal, or `null` when the entry genuinely
|
|
30
|
+
* does not exist in that durability.
|
|
31
|
+
*
|
|
32
|
+
* Transport errors are NOT swallowed — they propagate so a caller never mistakes
|
|
33
|
+
* a flaky RPC for an absent entry.
|
|
34
|
+
*/
|
|
35
|
+
export async function readContractData(rpc, contractId, key, durability) {
|
|
36
|
+
const { entries } = await rpc.getLedgerEntries(contractDataLedgerKey(contractId, key, durability));
|
|
37
|
+
const entry = entries[0];
|
|
38
|
+
return entry ? entry.val.contractData().val() : null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Whether a contract-data entry exists in the given durability.
|
|
42
|
+
*
|
|
43
|
+
* Returns `false` only on a genuine not-found; a transport error throws (so
|
|
44
|
+
* callers conclude eviction exclusively from an authoritative not-found).
|
|
45
|
+
*/
|
|
46
|
+
export async function contractDataExists(rpc, contractId, key, durability) {
|
|
47
|
+
return (await readContractData(rpc, contractId, key, durability)) !== null;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=rpc-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-data.js","sourceRoot":"","sources":["../src/rpc-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAe,MAAM,0BAA0B,CAAC;AAEnE,oFAAoF;AACpF,MAAM,UAAU,qBAAqB,CACnC,UAAkB,EAClB,GAAc,EACd,UAAsB;IAEtB,OAAO,GAAG,CAAC,SAAS,CAAC,YAAY,CAC/B,IAAI,GAAG,CAAC,qBAAqB,CAAC;QAC5B,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE;QACtD,GAAG;QACH,UAAU,EACR,UAAU,KAAK,UAAU,CAAC,SAAS;YACjC,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,SAAS,EAAE;YACxC,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,UAAU,EAAE;KAC9C,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAW,EACX,UAAkB,EAClB,GAAc,EACd,UAAsB;IAEtB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAC5C,qBAAqB,CAAC,UAAU,EAAE,GAAG,EAAE,UAAU,CAAC,CACnD,CAAC;IACF,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAW,EACX,UAAkB,EAClB,GAAc,EACd,UAAsB;IAEtB,OAAO,CAAC,MAAM,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,KAAK,IAAI,CAAC;AAC7E,CAAC"}
|
package/dist/sac.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stellar Asset Contract (SEP-41) helpers.
|
|
3
|
+
*
|
|
4
|
+
* DECISION (todo 950): keep the generated `sac-sdk` client rather than collapsing
|
|
5
|
+
* it to a bare `buildTokenTransferHostFunction` helper. The demo needs the full
|
|
6
|
+
* SEP-41 surface (balance, name/symbol/decimals reads, transfer) for token UX,
|
|
7
|
+
* which a transfer-only host-function builder cannot provide. We ALSO expose
|
|
8
|
+
* {@link buildTokenTransferHostFunction} for the low-level relayer `{func,auth}`
|
|
9
|
+
* path. (`sac-sdk` regeneration from a canonical source is handled in B4.)
|
|
10
|
+
*
|
|
11
|
+
* @packageDocumentation
|
|
12
|
+
*/
|
|
13
|
+
import { xdr } from "@stellar/stellar-sdk";
|
|
14
|
+
import { Client as SacClient } from "sac-sdk";
|
|
15
|
+
/** A thin factory around the generated SEP-41 `sac-sdk` client. */
|
|
16
|
+
export declare class SACClient {
|
|
17
|
+
readonly networkPassphrase: string;
|
|
18
|
+
readonly rpcUrl: string;
|
|
19
|
+
constructor(options: {
|
|
20
|
+
networkPassphrase: string;
|
|
21
|
+
rpcUrl: string;
|
|
22
|
+
});
|
|
23
|
+
/** Build a SEP-41 client for a specific SAC/token contract. */
|
|
24
|
+
getSACClient(sacContractId: string): SacClient;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build a raw SEP-41 `transfer(from, to, amount)` host function, for the
|
|
28
|
+
* low-level relayer `{ func, auth }` submission path (no client instance needed).
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildTokenTransferHostFunction(tokenContract: string, from: string, to: string, amountInStroops: bigint): xdr.HostFunction;
|
|
31
|
+
//# sourceMappingURL=sac.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sac.d.ts","sourceRoot":"","sources":["../src/sac.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAW,GAAG,EAAiB,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAE9C,mEAAmE;AACnE,qBAAa,SAAS;IACpB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,OAAO,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAKlE,+DAA+D;IAC/D,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS;CAO/C;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM,GACtB,GAAG,CAAC,YAAY,CAYlB"}
|
package/dist/sac.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stellar Asset Contract (SEP-41) helpers.
|
|
3
|
+
*
|
|
4
|
+
* DECISION (todo 950): keep the generated `sac-sdk` client rather than collapsing
|
|
5
|
+
* it to a bare `buildTokenTransferHostFunction` helper. The demo needs the full
|
|
6
|
+
* SEP-41 surface (balance, name/symbol/decimals reads, transfer) for token UX,
|
|
7
|
+
* which a transfer-only host-function builder cannot provide. We ALSO expose
|
|
8
|
+
* {@link buildTokenTransferHostFunction} for the low-level relayer `{func,auth}`
|
|
9
|
+
* path. (`sac-sdk` regeneration from a canonical source is handled in B4.)
|
|
10
|
+
*
|
|
11
|
+
* @packageDocumentation
|
|
12
|
+
*/
|
|
13
|
+
import { Address, xdr, nativeToScVal } from "@stellar/stellar-sdk";
|
|
14
|
+
import { Client as SacClient } from "sac-sdk";
|
|
15
|
+
/** A thin factory around the generated SEP-41 `sac-sdk` client. */
|
|
16
|
+
export class SACClient {
|
|
17
|
+
networkPassphrase;
|
|
18
|
+
rpcUrl;
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.networkPassphrase = options.networkPassphrase;
|
|
21
|
+
this.rpcUrl = options.rpcUrl;
|
|
22
|
+
}
|
|
23
|
+
/** Build a SEP-41 client for a specific SAC/token contract. */
|
|
24
|
+
getSACClient(sacContractId) {
|
|
25
|
+
return new SacClient({
|
|
26
|
+
contractId: sacContractId,
|
|
27
|
+
networkPassphrase: this.networkPassphrase,
|
|
28
|
+
rpcUrl: this.rpcUrl,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Build a raw SEP-41 `transfer(from, to, amount)` host function, for the
|
|
34
|
+
* low-level relayer `{ func, auth }` submission path (no client instance needed).
|
|
35
|
+
*/
|
|
36
|
+
export function buildTokenTransferHostFunction(tokenContract, from, to, amountInStroops) {
|
|
37
|
+
return xdr.HostFunction.hostFunctionTypeInvokeContract(new xdr.InvokeContractArgs({
|
|
38
|
+
contractAddress: Address.fromString(tokenContract).toScAddress(),
|
|
39
|
+
functionName: "transfer",
|
|
40
|
+
args: [
|
|
41
|
+
xdr.ScVal.scvAddress(Address.fromString(from).toScAddress()),
|
|
42
|
+
xdr.ScVal.scvAddress(Address.fromString(to).toScAddress()),
|
|
43
|
+
nativeToScVal(amountInStroops, { type: "i128" }),
|
|
44
|
+
],
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=sac.js.map
|
package/dist/sac.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sac.js","sourceRoot":"","sources":["../src/sac.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAE9C,mEAAmE;AACnE,MAAM,OAAO,SAAS;IACX,iBAAiB,CAAS;IAC1B,MAAM,CAAS;IAExB,YAAY,OAAsD;QAChE,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;QACnD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC/B,CAAC;IAED,+DAA+D;IAC/D,YAAY,CAAC,aAAqB;QAChC,OAAO,IAAI,SAAS,CAAC;YACnB,UAAU,EAAE,aAAa;YACzB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;IACL,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,8BAA8B,CAC5C,aAAqB,EACrB,IAAY,EACZ,EAAU,EACV,eAAuB;IAEvB,OAAO,GAAG,CAAC,YAAY,CAAC,8BAA8B,CACpD,IAAI,GAAG,CAAC,kBAAkB,CAAC;QACzB,eAAe,EAAE,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE;QAChE,YAAY,EAAE,UAAU;QACxB,IAAI,EAAE;YACJ,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAC5D,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAC1D,aAAa,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SACjD;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `PasskeyServer` — the SERVER-ONLY counterpart to {@link PasskeyKit}.
|
|
3
|
+
*
|
|
4
|
+
* It holds the relayer API key and therefore must never run in a browser
|
|
5
|
+
* bundle: it is exported exclusively from the `passkey-kit/server` subpath so a
|
|
6
|
+
* bundler can't pull it into client code, and its config must come from
|
|
7
|
+
* server-side environment variables (never `VITE_`-prefixed).
|
|
8
|
+
*
|
|
9
|
+
* Responsibilities: fee-sponsored submission via {@link RelayerClient} and
|
|
10
|
+
* convenience signer-discovery helpers that delegate to a {@link MercuryIndexer}
|
|
11
|
+
* over Mercury's keyless hosted passkey-indexer. (`MercuryIndexer` itself is
|
|
12
|
+
* keyless and browser-safe — exported from the main `passkey-kit` entry; these
|
|
13
|
+
* server methods are a thin convenience over it.)
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { type Transaction } from "@stellar/stellar-sdk";
|
|
18
|
+
import { Server } from "@stellar/stellar-sdk/rpc";
|
|
19
|
+
import { AssembledTransaction } from "@stellar/stellar-sdk/contract";
|
|
20
|
+
import { type RelayerClientConfig, type RelayerSubmitOptions } from "./relayer.js";
|
|
21
|
+
import type { WalletSigner } from "./indexer/index.js";
|
|
22
|
+
import type { TransactionResult } from "./types.js";
|
|
23
|
+
export { RelayerClient, type RelayerClientConfig, type RelayerSubmitOptions, } from "./relayer.js";
|
|
24
|
+
/** Mercury hosted passkey-indexer configuration (keyless). */
|
|
25
|
+
export interface MercuryConfig {
|
|
26
|
+
/**
|
|
27
|
+
* Passkey-indexer base URL. Defaults to the network's hosted endpoint
|
|
28
|
+
* (`https://{testnet,mainnet}.mercurydata.app/rest/passkey-indexer`); set it
|
|
29
|
+
* only to point at a self-hosted instance.
|
|
30
|
+
*/
|
|
31
|
+
url?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Configuration for a {@link PasskeyServer}. */
|
|
34
|
+
export interface PasskeyServerConfig {
|
|
35
|
+
/** Network passphrase (required). */
|
|
36
|
+
networkPassphrase: string;
|
|
37
|
+
/** Stellar RPC URL (needed for temporary-signer eviction probes). */
|
|
38
|
+
rpcUrl?: string;
|
|
39
|
+
/** Relayer configuration for fee-sponsored submission. */
|
|
40
|
+
relayer?: RelayerClientConfig;
|
|
41
|
+
/** Mercury indexer configuration. */
|
|
42
|
+
mercury?: MercuryConfig;
|
|
43
|
+
}
|
|
44
|
+
export declare class PasskeyServer {
|
|
45
|
+
readonly networkPassphrase: string;
|
|
46
|
+
readonly rpc?: Server;
|
|
47
|
+
private readonly relayer?;
|
|
48
|
+
private readonly mercury?;
|
|
49
|
+
constructor(config: PasskeyServerConfig);
|
|
50
|
+
/**
|
|
51
|
+
* Submit a transaction via the relayer for fee sponsorship.
|
|
52
|
+
*
|
|
53
|
+
* invokeHostFunction transactions without source-account auth use the preferred
|
|
54
|
+
* `{ func, auth }` Soroban path; everything else (deploys, source-account auth)
|
|
55
|
+
* is fee-bumped via the `{ xdr }` envelope path. Never throws — returns a typed
|
|
56
|
+
* {@link TransactionResult}.
|
|
57
|
+
*/
|
|
58
|
+
send(input: AssembledTransaction<unknown> | Transaction | string, options?: RelayerSubmitOptions): Promise<TransactionResult>;
|
|
59
|
+
/** Poll a `skipWait` submission by its relayer transaction id. */
|
|
60
|
+
getTransaction(transactionId: string): Promise<TransactionResult>;
|
|
61
|
+
private requireMercury;
|
|
62
|
+
/**
|
|
63
|
+
* Enumerate a wallet's signers via Mercury. Temporary signers whose ledger
|
|
64
|
+
* entry has been evicted are flagged `status: "evicted"` when this server was
|
|
65
|
+
* given an `rpcUrl` (the indexer can't observe TTL eviction directly).
|
|
66
|
+
*/
|
|
67
|
+
getSigners(contractId: string): Promise<WalletSigner[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Reverse lookup: find the wallet(s) a signer belongs to via Mercury.
|
|
70
|
+
*
|
|
71
|
+
* @returns the confirmed address at `index`, or `undefined` if there are none.
|
|
72
|
+
*/
|
|
73
|
+
getContractId(options: {
|
|
74
|
+
keyId?: string;
|
|
75
|
+
publicKey?: string;
|
|
76
|
+
policy?: string;
|
|
77
|
+
}, index?: number): Promise<string | undefined>;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAiB,KAAK,mBAAmB,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AASlG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAIpD,OAAO,EACL,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC;AAEtB,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,iDAAiD;AACjD,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,qCAAqC;IACrC,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAmCD,qBAAa,aAAa;IACxB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAiB;gBAE9B,MAAM,EAAE,mBAAmB;IAgCvC;;;;;;;OAOG;IACG,IAAI,CACR,KAAK,EAAE,oBAAoB,CAAC,OAAO,CAAC,GAAG,WAAW,GAAG,MAAM,EAC3D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAmC7B,kEAAkE;IAClE,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAgBjE,OAAO,CAAC,cAAc;IAUtB;;;;OAIG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAIvD;;;;OAIG;IACG,aAAa,CACjB,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAChE,KAAK,SAAI,GACR,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAmB/B"}
|