@pincerpay/solana 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PincerPay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # @pincerpay/solana
2
+
3
+ Solana infrastructure integrations for PincerPay: Kora gasless transactions and Squads SPN smart accounts.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @pincerpay/solana
9
+ ```
10
+
11
+ ## Kora (Gasless Transactions)
12
+
13
+ Agents pay transaction fees in USDC instead of SOL via Kora signer nodes.
14
+
15
+ ### Quick Start
16
+
17
+ ```typescript
18
+ import { createKoraClient, createKoraFacilitatorSvmSigner } from "@pincerpay/solana/kora";
19
+
20
+ // Low-level client
21
+ const kora = createKoraClient({
22
+ rpcUrl: "https://your-kora-node.example.com",
23
+ apiKey: "optional-api-key",
24
+ });
25
+
26
+ const feePayer = await kora.getFeePayer();
27
+
28
+ // x402 facilitator integration
29
+ const signer = createKoraFacilitatorSvmSigner({
30
+ config: { rpcUrl: "https://your-kora-node.example.com" },
31
+ rpcUrls: { "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1": "https://api.devnet.solana.com" },
32
+ });
33
+
34
+ await signer.init(); // Fetches fee payer address
35
+ ```
36
+
37
+ ### API Reference
38
+
39
+ ```typescript
40
+ interface KoraConfig {
41
+ rpcUrl: string;
42
+ apiKey?: string;
43
+ }
44
+
45
+ function createKoraClient(config: KoraConfig): KoraRpcClient;
46
+
47
+ function createKoraFacilitatorSvmSigner(options: {
48
+ config: KoraConfig;
49
+ rpcUrls?: Record<string, string>;
50
+ }): FacilitatorSvmSigner & { init(): Promise<void> };
51
+
52
+ function parseKoraConfig(
53
+ env: Record<string, string | undefined>
54
+ ): KoraConfig | null;
55
+ ```
56
+
57
+ ## Squads SPN (Smart Accounts)
58
+
59
+ Decentralized policy co-signer for agent sub-accounts with on-chain spending limits.
60
+
61
+ ### Quick Start
62
+
63
+ ```typescript
64
+ import {
65
+ deriveSmartAccountPda,
66
+ createSpendingLimit,
67
+ checkSpendingLimit,
68
+ SpendingLimitPeriod,
69
+ } from "@pincerpay/solana/squads";
70
+
71
+ // Derive smart account PDA
72
+ const [smartAccountPda] = await deriveSmartAccountPda(creatorAddress, 0);
73
+
74
+ // Create a daily spending limit
75
+ const ix = await createSpendingLimit(
76
+ {
77
+ smartAccountPda,
78
+ mint: usdcMintAddress,
79
+ amount: 10_000_000n, // 10 USDC
80
+ period: SpendingLimitPeriod.Day,
81
+ members: [agentAddress],
82
+ destinations: [merchantAddress],
83
+ },
84
+ 0, // spending limit index
85
+ authorityAddress
86
+ );
87
+
88
+ // Check remaining allowance
89
+ const limit = await checkSpendingLimit(smartAccountPda, 0, rpcUrl);
90
+ // { exists: true, remainingAmount: 8_000_000n, period: "Day" }
91
+ ```
92
+
93
+ ### API Reference
94
+
95
+ #### PDA Derivation
96
+
97
+ ```typescript
98
+ async function deriveSmartAccountPda(
99
+ creator: Address, accountIndex: number, programId?: Address
100
+ ): Promise<[Address, number]>;
101
+
102
+ async function deriveSettingsPda(
103
+ smartAccountPda: Address, programId?: Address
104
+ ): Promise<[Address, number]>;
105
+
106
+ async function deriveSpendingLimitPda(
107
+ smartAccountPda: Address, spendingLimitIndex: number, programId?: Address
108
+ ): Promise<[Address, number]>;
109
+ ```
110
+
111
+ #### Spending Limit Management
112
+
113
+ ```typescript
114
+ async function createSpendingLimit(
115
+ config: SpendingLimitConfig, spendingLimitIndex: number, authority: Address
116
+ ): Promise<Instruction>;
117
+
118
+ async function checkSpendingLimit(
119
+ smartAccountPda: Address, spendingLimitIndex: number, rpcUrl: string
120
+ ): Promise<{ exists: boolean; remainingAmount?: bigint; period?: SpendingLimitPeriod } | null>;
121
+
122
+ async function revokeSpendingLimit(
123
+ smartAccountPda: Address, spendingLimitIndex: number, authority: Address, rentCollector: Address
124
+ ): Promise<Instruction>;
125
+ ```
126
+
127
+ #### Types
128
+
129
+ ```typescript
130
+ enum SpendingLimitPeriod {
131
+ OneTime = 0,
132
+ Day = 1,
133
+ Week = 2,
134
+ Month = 3,
135
+ }
136
+
137
+ interface SpendingLimitConfig {
138
+ smartAccountPda: Address;
139
+ mint: Address;
140
+ amount: bigint;
141
+ period: SpendingLimitPeriod;
142
+ members: Address[];
143
+ destinations: Address[];
144
+ }
145
+
146
+ interface SmartAccountConfig {
147
+ creator: Address;
148
+ accountIndex: number;
149
+ members: Address[];
150
+ threshold: number;
151
+ }
152
+
153
+ const SQUADS_PROGRAM_ID = "SMRTzfY6DfH5ik3TKiyLFfXexV8uSG3d2UksSCYdunG";
154
+ ```
155
+
156
+ ## Common Patterns
157
+
158
+ ### Kora + Squads together
159
+
160
+ ```typescript
161
+ import { createKoraFacilitatorSvmSigner } from "@pincerpay/solana/kora";
162
+ import { deriveSmartAccountPda, checkSpendingLimit } from "@pincerpay/solana/squads";
163
+
164
+ // Agent pays gas in USDC (Kora) + has on-chain spending limits (Squads)
165
+ const signer = createKoraFacilitatorSvmSigner({ config: koraConfig });
166
+ const [smartAccount] = await deriveSmartAccountPda(creator, 0);
167
+ const limit = await checkSpendingLimit(smartAccount, 0, rpcUrl);
168
+ ```
169
+
170
+ ## Anti-Patterns
171
+
172
+ ### Don't skip `signer.init()` for Kora
173
+
174
+ The Kora signer must call `init()` before use — it fetches the fee payer address from the Kora node.
175
+
176
+ ### Don't use Squads on EVM
177
+
178
+ Squads SPN is Solana-only. For EVM agent permissions, use ERC-7715 session keys instead.
@@ -0,0 +1,3 @@
1
+ export * from "./kora/index.js";
2
+ export * from "./squads/index.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./kora/index.js";
2
+ export * from "./squads/index.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ export declare const koraConfigSchema: z.ZodObject<{
3
+ /** Kora RPC endpoint URL */
4
+ rpcUrl: z.ZodString;
5
+ /** Kora API key for authentication (optional, depends on Kora node config) */
6
+ apiKey: z.ZodOptional<z.ZodString>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ rpcUrl: string;
9
+ apiKey?: string | undefined;
10
+ }, {
11
+ rpcUrl: string;
12
+ apiKey?: string | undefined;
13
+ }>;
14
+ export type KoraConfig = z.infer<typeof koraConfigSchema>;
15
+ /**
16
+ * Parse Kora configuration from environment variables.
17
+ * Returns null if KORA_RPC_URL is not set.
18
+ */
19
+ export declare function parseKoraConfig(env: Record<string, string | undefined>): KoraConfig | null;
20
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/kora/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;IAC3B,4BAA4B;;IAE5B,8EAA8E;;;;;;;;EAE9E,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,UAAU,GAAG,IAAI,CAM1F"}
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ export const koraConfigSchema = z.object({
3
+ /** Kora RPC endpoint URL */
4
+ rpcUrl: z.string().url(),
5
+ /** Kora API key for authentication (optional, depends on Kora node config) */
6
+ apiKey: z.string().optional(),
7
+ });
8
+ /**
9
+ * Parse Kora configuration from environment variables.
10
+ * Returns null if KORA_RPC_URL is not set.
11
+ */
12
+ export function parseKoraConfig(env) {
13
+ if (!env.KORA_RPC_URL)
14
+ return null;
15
+ return koraConfigSchema.parse({
16
+ rpcUrl: env.KORA_RPC_URL,
17
+ apiKey: env.KORA_API_KEY,
18
+ });
19
+ }
20
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/kora/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,4BAA4B;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACxB,8EAA8E;IAC9E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAIH;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAuC;IACrE,IAAI,CAAC,GAAG,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,gBAAgB,CAAC,KAAK,CAAC;QAC5B,MAAM,EAAE,GAAG,CAAC,YAAY;QACxB,MAAM,EAAE,GAAG,CAAC,YAAY;KACzB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { createKoraFacilitatorSvmSigner, createKoraClient } from "./signer.js";
2
+ export type { KoraRpcClient } from "./signer.js";
3
+ export { parseKoraConfig, koraConfigSchema } from "./config.js";
4
+ export type { KoraConfig } from "./config.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/kora/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createKoraFacilitatorSvmSigner, createKoraClient } from "./signer.js";
2
+ export { parseKoraConfig, koraConfigSchema } from "./config.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/kora/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/E,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,52 @@
1
+ import type { FacilitatorSvmSigner } from "@x402/svm";
2
+ import type { KoraConfig } from "./config.js";
3
+ /**
4
+ * Kora RPC client interface — minimal subset of JSON-RPC methods we use.
5
+ * Kora exposes standard Solana RPC + custom methods for gasless transactions.
6
+ */
7
+ interface KoraPayerSignerResult {
8
+ signer_address: string;
9
+ payment_address: string;
10
+ }
11
+ interface KoraSignResult {
12
+ signature: string;
13
+ signed_transaction: string;
14
+ signer_pubkey: string;
15
+ }
16
+ interface KoraRpcClient {
17
+ /** Fetch the Kora signer node's payer signer info (address + payment destination) */
18
+ getPayerSigner(): Promise<KoraPayerSignerResult>;
19
+ /** Sign a base64-encoded transaction with the Kora fee payer */
20
+ signTransaction(params: {
21
+ transaction: string;
22
+ }): Promise<KoraSignResult>;
23
+ /** Sign and send a base64-encoded transaction via the Kora signer node */
24
+ signAndSendTransaction(params: {
25
+ transaction: string;
26
+ }): Promise<KoraSignResult>;
27
+ }
28
+ /**
29
+ * Minimal Kora JSON-RPC client. Calls Kora's custom RPC methods.
30
+ */
31
+ declare function createKoraClient(config: KoraConfig): KoraRpcClient;
32
+ interface KoraFacilitatorSvmSignerOptions {
33
+ config: KoraConfig;
34
+ /** Override Solana RPC URLs per network (CAIP-2 → URL) */
35
+ rpcUrls?: Record<string, string>;
36
+ }
37
+ /**
38
+ * Creates a FacilitatorSvmSigner backed by a Kora signer node.
39
+ *
40
+ * Kora handles fee payment in USDC (or other SPL tokens) instead of SOL.
41
+ * The facilitator delegates transaction signing to the Kora node which:
42
+ * 1. Adds its fee payer as the transaction fee payer
43
+ * 2. Signs the transaction with its fee payer key
44
+ * 3. Charges the agent in USDC for gas costs
45
+ *
46
+ * IMPORTANT: Call `await signer.init()` before using — fetches the fee payer address.
47
+ */
48
+ export declare function createKoraFacilitatorSvmSigner(options: KoraFacilitatorSvmSignerOptions): FacilitatorSvmSigner & {
49
+ init(): Promise<void>;
50
+ };
51
+ export { createKoraClient, type KoraRpcClient };
52
+ //# sourceMappingURL=signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/kora/signer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;GAGG;AACH,UAAU,qBAAqB;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,aAAa;IACrB,qFAAqF;IACrF,cAAc,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACjD,gEAAgE;IAChE,eAAe,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1E,0EAA0E;IAC1E,sBAAsB,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAClF;AAED;;GAEG;AACH,iBAAS,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAoC3D;AAED,UAAU,+BAA+B;IACvC,MAAM,EAAE,UAAU,CAAC;IACnB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,+BAA+B,GACvC,oBAAoB,GAAG;IAAE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA6HlD;AAED,OAAO,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,CAAC"}
@@ -0,0 +1,151 @@
1
+ import { createSolanaRpc, signature } from "@solana/kit";
2
+ /**
3
+ * Minimal Kora JSON-RPC client. Calls Kora's custom RPC methods.
4
+ */
5
+ function createKoraClient(config) {
6
+ let requestId = 0;
7
+ async function rpcCall(method, params) {
8
+ const headers = { "Content-Type": "application/json" };
9
+ if (config.apiKey) {
10
+ headers["Authorization"] = `Bearer ${config.apiKey}`;
11
+ }
12
+ const res = await fetch(config.rpcUrl, {
13
+ method: "POST",
14
+ headers,
15
+ body: JSON.stringify({
16
+ jsonrpc: "2.0",
17
+ id: ++requestId,
18
+ method,
19
+ params: params ?? [],
20
+ }),
21
+ });
22
+ if (!res.ok) {
23
+ throw new Error(`Kora RPC error: ${res.status} ${res.statusText}`);
24
+ }
25
+ const json = (await res.json());
26
+ if (json.error) {
27
+ throw new Error(`Kora RPC error [${json.error.code}]: ${json.error.message}`);
28
+ }
29
+ return json.result;
30
+ }
31
+ return {
32
+ getPayerSigner: () => rpcCall("getPayerSigner"),
33
+ signTransaction: (params) => rpcCall("signTransaction", params),
34
+ signAndSendTransaction: (params) => rpcCall("signAndSendTransaction", params),
35
+ };
36
+ }
37
+ /**
38
+ * Creates a FacilitatorSvmSigner backed by a Kora signer node.
39
+ *
40
+ * Kora handles fee payment in USDC (or other SPL tokens) instead of SOL.
41
+ * The facilitator delegates transaction signing to the Kora node which:
42
+ * 1. Adds its fee payer as the transaction fee payer
43
+ * 2. Signs the transaction with its fee payer key
44
+ * 3. Charges the agent in USDC for gas costs
45
+ *
46
+ * IMPORTANT: Call `await signer.init()` before using — fetches the fee payer address.
47
+ */
48
+ export function createKoraFacilitatorSvmSigner(options) {
49
+ const { config, rpcUrls } = options;
50
+ const kora = createKoraClient(config);
51
+ // Cached fee payer address — populated during init()
52
+ let feePayerAddress = null;
53
+ // Cache Solana RPC connections for simulation/confirmation
54
+ const rpcCache = new Map();
55
+ function getSolanaRpc(network) {
56
+ let rpc = rpcCache.get(network);
57
+ if (!rpc) {
58
+ const url = rpcUrls?.[network] ?? "https://api.devnet.solana.com";
59
+ rpc = createSolanaRpc(url);
60
+ rpcCache.set(network, rpc);
61
+ }
62
+ return rpc;
63
+ }
64
+ const signer = {
65
+ /**
66
+ * Fetch the Kora fee payer address. Must be called before getAddresses().
67
+ */
68
+ async init() {
69
+ const result = await kora.getPayerSigner();
70
+ feePayerAddress = result.signer_address;
71
+ },
72
+ getAddresses() {
73
+ if (!feePayerAddress) {
74
+ throw new Error("KoraFacilitatorSvmSigner not initialized — call init() first");
75
+ }
76
+ return [feePayerAddress];
77
+ },
78
+ async signTransaction(transaction, _feePayer, _network) {
79
+ const result = await kora.signTransaction({ transaction });
80
+ return result.signed_transaction;
81
+ },
82
+ async simulateTransaction(transaction, network) {
83
+ const rpc = getSolanaRpc(network);
84
+ // Simulate using the standard Solana RPC — cast transaction to expected encoded type
85
+ const result = await rpc
86
+ .simulateTransaction(transaction, {
87
+ commitment: "confirmed",
88
+ replaceRecentBlockhash: true,
89
+ encoding: "base64",
90
+ })
91
+ .send();
92
+ if (result.value.err) {
93
+ throw new Error(`Transaction simulation failed: ${JSON.stringify(result.value.err)}`);
94
+ }
95
+ },
96
+ async sendTransaction(transaction, network) {
97
+ // Transaction is already fully signed by signTransaction() — submit directly
98
+ // to Solana RPC instead of Kora's signAndSendTransaction (which would re-sign).
99
+ // Use raw fetch to avoid @solana/kit type/encoding issues.
100
+ const url = rpcUrls?.[network] ?? "https://api.devnet.solana.com";
101
+ const res = await fetch(url, {
102
+ method: "POST",
103
+ headers: { "Content-Type": "application/json" },
104
+ body: JSON.stringify({
105
+ jsonrpc: "2.0",
106
+ id: 1,
107
+ method: "sendTransaction",
108
+ params: [transaction, {
109
+ encoding: "base64",
110
+ skipPreflight: false,
111
+ preflightCommitment: "confirmed",
112
+ }],
113
+ }),
114
+ });
115
+ const json = (await res.json());
116
+ if (json.error) {
117
+ throw new Error(`Solana sendTransaction failed [${json.error.code}]: ${json.error.message}` +
118
+ (json.error.data ? ` (${JSON.stringify(json.error.data)})` : ""));
119
+ }
120
+ return json.result;
121
+ },
122
+ async confirmTransaction(sig, network) {
123
+ const rpc = getSolanaRpc(network);
124
+ const brandedSig = signature(sig);
125
+ // Poll for confirmation with timeout
126
+ const timeout = 30_000;
127
+ const interval = 2_000;
128
+ const start = Date.now();
129
+ while (Date.now() - start < timeout) {
130
+ const statuses = await rpc
131
+ .getSignatureStatuses([brandedSig], { searchTransactionHistory: true })
132
+ .send();
133
+ const status = statuses.value[0];
134
+ if (status) {
135
+ if (status.err) {
136
+ throw new Error(`Transaction failed: ${JSON.stringify(status.err)}`);
137
+ }
138
+ if (status.confirmationStatus === "confirmed" ||
139
+ status.confirmationStatus === "finalized") {
140
+ return;
141
+ }
142
+ }
143
+ await new Promise((resolve) => setTimeout(resolve, interval));
144
+ }
145
+ throw new Error(`Transaction confirmation timed out after ${timeout}ms`);
146
+ },
147
+ };
148
+ return signer;
149
+ }
150
+ export { createKoraClient };
151
+ //# sourceMappingURL=signer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.js","sourceRoot":"","sources":["../../src/kora/signer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Address } from "@solana/kit";
2
+ import { SQUADS_PROGRAM_ID } from "./types.js";
3
+ export { SQUADS_PROGRAM_ID };
4
+ /**
5
+ * Derive the Smart Account PDA.
6
+ * Seeds: ["smart_account", creator, account_index (u32 LE)]
7
+ */
8
+ export declare function deriveSmartAccountPda(creator: Address, accountIndex: number, programId?: Address): Promise<readonly [Address, number]>;
9
+ /**
10
+ * Derive the Settings PDA for a Smart Account.
11
+ * Seeds: ["settings", smart_account_pda]
12
+ */
13
+ export declare function deriveSettingsPda(smartAccountPda: Address, programId?: Address): Promise<readonly [Address, number]>;
14
+ /**
15
+ * Derive a Spending Limit PDA.
16
+ * Seeds: ["spending_limit", smart_account_pda, spending_limit_index (u32 LE)]
17
+ */
18
+ export declare function deriveSpendingLimitPda(smartAccountPda: Address, spendingLimitIndex: number, programId?: Address): Promise<readonly [Address, number]>;
19
+ //# sourceMappingURL=accounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../src/squads/accounts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,OAA2B,GACrC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAarC;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,OAAO,EACxB,SAAS,GAAE,OAA2B,GACrC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CASrC;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,eAAe,EAAE,OAAO,EACxB,kBAAkB,EAAE,MAAM,EAC1B,SAAS,GAAE,OAA2B,GACrC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAarC"}
@@ -0,0 +1,52 @@
1
+ import { getAddressEncoder, getProgramDerivedAddress } from "@solana/kit";
2
+ import { SQUADS_PROGRAM_ID } from "./types.js";
3
+ export { SQUADS_PROGRAM_ID };
4
+ /**
5
+ * Derive the Smart Account PDA.
6
+ * Seeds: ["smart_account", creator, account_index (u32 LE)]
7
+ */
8
+ export async function deriveSmartAccountPda(creator, accountIndex, programId = SQUADS_PROGRAM_ID) {
9
+ const encoder = getAddressEncoder();
10
+ const indexBuffer = new Uint8Array(4);
11
+ new DataView(indexBuffer.buffer).setUint32(0, accountIndex, true); // little-endian
12
+ return getProgramDerivedAddress({
13
+ programAddress: programId,
14
+ seeds: [
15
+ new TextEncoder().encode("smart_account"),
16
+ encoder.encode(creator),
17
+ indexBuffer,
18
+ ],
19
+ });
20
+ }
21
+ /**
22
+ * Derive the Settings PDA for a Smart Account.
23
+ * Seeds: ["settings", smart_account_pda]
24
+ */
25
+ export async function deriveSettingsPda(smartAccountPda, programId = SQUADS_PROGRAM_ID) {
26
+ const encoder = getAddressEncoder();
27
+ return getProgramDerivedAddress({
28
+ programAddress: programId,
29
+ seeds: [
30
+ new TextEncoder().encode("settings"),
31
+ encoder.encode(smartAccountPda),
32
+ ],
33
+ });
34
+ }
35
+ /**
36
+ * Derive a Spending Limit PDA.
37
+ * Seeds: ["spending_limit", smart_account_pda, spending_limit_index (u32 LE)]
38
+ */
39
+ export async function deriveSpendingLimitPda(smartAccountPda, spendingLimitIndex, programId = SQUADS_PROGRAM_ID) {
40
+ const encoder = getAddressEncoder();
41
+ const indexBuffer = new Uint8Array(4);
42
+ new DataView(indexBuffer.buffer).setUint32(0, spendingLimitIndex, true);
43
+ return getProgramDerivedAddress({
44
+ programAddress: programId,
45
+ seeds: [
46
+ new TextEncoder().encode("spending_limit"),
47
+ encoder.encode(smartAccountPda),
48
+ indexBuffer,
49
+ ],
50
+ });
51
+ }
52
+ //# sourceMappingURL=accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/squads/accounts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAgB,EAChB,YAAoB,EACpB,YAAqB,iBAAiB;IAEtC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,gBAAgB;IAEnF,OAAO,wBAAwB,CAAC;QAC9B,cAAc,EAAE,SAAS;QACzB,KAAK,EAAE;YACL,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC;YACzC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;YACvB,WAAW;SACZ;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,eAAwB,EACxB,YAAqB,iBAAiB;IAEtC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,OAAO,wBAAwB,CAAC;QAC9B,cAAc,EAAE,SAAS;QACzB,KAAK,EAAE;YACL,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC;YACpC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC;SAChC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,eAAwB,EACxB,kBAA0B,EAC1B,YAAqB,iBAAiB;IAEtC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;IAExE,OAAO,wBAAwB,CAAC;QAC9B,cAAc,EAAE,SAAS;QACzB,KAAK,EAAE;YACL,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC;YAC1C,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC;YAC/B,WAAW;SACZ;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { deriveSmartAccountPda, deriveSettingsPda, deriveSpendingLimitPda, SQUADS_PROGRAM_ID } from "./accounts.js";
2
+ export { createSmartAccountInstruction, addSpendingLimitInstruction, useSpendingLimitInstruction, removeSpendingLimitInstruction } from "./instructions.js";
3
+ export { createSpendingLimit, checkSpendingLimit, revokeSpendingLimit } from "./spending.js";
4
+ export { SpendingLimitPeriod } from "./types.js";
5
+ export type { SpendingLimitConfig, SmartAccountConfig } from "./types.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/squads/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,6BAA6B,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAC5J,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ // Squads Smart Account module — implemented in task S2b
2
+ export { deriveSmartAccountPda, deriveSettingsPda, deriveSpendingLimitPda, SQUADS_PROGRAM_ID } from "./accounts.js";
3
+ export { createSmartAccountInstruction, addSpendingLimitInstruction, useSpendingLimitInstruction, removeSpendingLimitInstruction } from "./instructions.js";
4
+ export { createSpendingLimit, checkSpendingLimit, revokeSpendingLimit } from "./spending.js";
5
+ export { SpendingLimitPeriod } from "./types.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/squads/index.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,6BAA6B,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAC5J,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { Address, Instruction } from "@solana/kit";
2
+ import { type SmartAccountConfig, type SpendingLimitConfig, SpendingLimitPeriod } from "./types.js";
3
+ /**
4
+ * Build a `createSmartAccount` instruction.
5
+ * Initializes a new Squads Smart Account with the given signers and threshold.
6
+ */
7
+ export declare function createSmartAccountInstruction(config: SmartAccountConfig): Promise<Instruction>;
8
+ /**
9
+ * Build an `addSpendingLimitAsAuthority` instruction.
10
+ * Sets a per-mint spending cap with time period on a Smart Account.
11
+ */
12
+ export declare function addSpendingLimitInstruction(config: SpendingLimitConfig, spendingLimitIndex: number, authority: Address): Promise<Instruction>;
13
+ /**
14
+ * Build a `useSpendingLimit` instruction.
15
+ * Spends within the limit — no proposal required.
16
+ */
17
+ export declare function useSpendingLimitInstruction(params: {
18
+ smartAccountPda: Address;
19
+ spendingLimitIndex: number;
20
+ /** Token mint (USDC) */
21
+ mint: Address;
22
+ /** Source token account (Smart Account's ATA) */
23
+ sourceTokenAccount: Address;
24
+ /** Destination token account */
25
+ destinationTokenAccount: Address;
26
+ /** Member (agent) signing the transaction */
27
+ member: Address;
28
+ /** Amount to spend (base units) */
29
+ amount: bigint;
30
+ }): Promise<Instruction>;
31
+ /**
32
+ * Build a `removeSpendingLimitAsAuthority` instruction.
33
+ * Revokes a spending limit from the Smart Account.
34
+ */
35
+ export declare function removeSpendingLimitInstruction(params: {
36
+ smartAccountPda: Address;
37
+ spendingLimitIndex: number;
38
+ authority: Address;
39
+ /** Account to receive the rent-exempt lamports */
40
+ rentCollector: Address;
41
+ }): Promise<Instruction>;
42
+ export { SpendingLimitPeriod };
43
+ //# sourceMappingURL=instructions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/squads/instructions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAqB,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AA+BvH;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,WAAW,CAAC,CAqCtB;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,mBAAmB,EAC3B,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,WAAW,CAAC,CAqDtB;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,MAAM,EAAE;IACxD,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,wBAAwB;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,iDAAiD;IACjD,kBAAkB,EAAE,OAAO,CAAC;IAC5B,gCAAgC;IAChC,uBAAuB,EAAE,OAAO,CAAC;IACjC,6CAA6C;IAC7C,MAAM,EAAE,OAAO,CAAC;IAChB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,WAAW,CAAC,CAwBvB;AAED;;;GAGG;AACH,wBAAsB,8BAA8B,CAAC,MAAM,EAAE;IAC3D,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,kDAAkD;IAClD,aAAa,EAAE,OAAO,CAAC;CACxB,GAAG,OAAO,CAAC,WAAW,CAAC,CAkBvB;AAGD,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,163 @@
1
+ import { getAddressEncoder } from "@solana/kit";
2
+ import { SQUADS_PROGRAM_ID, SpendingLimitPeriod } from "./types.js";
3
+ import { deriveSmartAccountPda, deriveSettingsPda, deriveSpendingLimitPda } from "./accounts.js";
4
+ // Anchor discriminators are first 8 bytes of sha256("global:<instruction_name>")
5
+ // Pre-computed for the 4 instructions we need
6
+ /** sha256("global:create_smart_account")[0..8] */
7
+ const CREATE_SMART_ACCOUNT_DISC = new Uint8Array([
8
+ 0x18, 0x46, 0xf0, 0x52, 0x88, 0xa5, 0x03, 0x26,
9
+ ]);
10
+ /** sha256("global:add_spending_limit_as_authority")[0..8] */
11
+ const ADD_SPENDING_LIMIT_DISC = new Uint8Array([
12
+ 0xd1, 0x81, 0xb2, 0x0f, 0x07, 0x0c, 0x79, 0xa2,
13
+ ]);
14
+ /** sha256("global:use_spending_limit")[0..8] */
15
+ const USE_SPENDING_LIMIT_DISC = new Uint8Array([
16
+ 0x65, 0x7b, 0x5a, 0xf7, 0x80, 0x5e, 0x89, 0x11,
17
+ ]);
18
+ /** sha256("global:remove_spending_limit_as_authority")[0..8] */
19
+ const REMOVE_SPENDING_LIMIT_DISC = new Uint8Array([
20
+ 0xc9, 0x18, 0x27, 0x0d, 0x3e, 0x5b, 0x7a, 0x4f,
21
+ ]);
22
+ /** System Program ID */
23
+ const SYSTEM_PROGRAM = "11111111111111111111111111111111";
24
+ /** SPL Token Program ID */
25
+ const TOKEN_PROGRAM = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
26
+ /**
27
+ * Build a `createSmartAccount` instruction.
28
+ * Initializes a new Squads Smart Account with the given signers and threshold.
29
+ */
30
+ export async function createSmartAccountInstruction(config) {
31
+ const [smartAccountPda] = await deriveSmartAccountPda(config.creator, config.accountIndex);
32
+ const [settingsPda] = await deriveSettingsPda(smartAccountPda);
33
+ // Serialize args: threshold (u16 LE) + members count (u32 LE) + members (32 bytes each)
34
+ const argsSize = 8 + 2 + 4 + config.members.length * 32;
35
+ const data = new Uint8Array(argsSize);
36
+ const view = new DataView(data.buffer);
37
+ let offset = 0;
38
+ // Discriminator
39
+ data.set(CREATE_SMART_ACCOUNT_DISC, offset);
40
+ offset += 8;
41
+ // Threshold (u16 LE)
42
+ view.setUint16(offset, config.threshold, true);
43
+ offset += 2;
44
+ // Members array (Borsh: u32 length prefix + items)
45
+ const encoder = getAddressEncoder();
46
+ view.setUint32(offset, config.members.length, true);
47
+ offset += 4;
48
+ for (const member of config.members) {
49
+ data.set(encoder.encode(member), offset);
50
+ offset += 32;
51
+ }
52
+ return {
53
+ programAddress: SQUADS_PROGRAM_ID,
54
+ accounts: [
55
+ { address: smartAccountPda, role: 1 }, // writable
56
+ { address: settingsPda, role: 1 }, // writable
57
+ { address: config.creator, role: 3 }, // writable + signer
58
+ { address: SYSTEM_PROGRAM, role: 0 }, // readonly
59
+ ],
60
+ data,
61
+ };
62
+ }
63
+ /**
64
+ * Build an `addSpendingLimitAsAuthority` instruction.
65
+ * Sets a per-mint spending cap with time period on a Smart Account.
66
+ */
67
+ export async function addSpendingLimitInstruction(config, spendingLimitIndex, authority) {
68
+ const [settingsPda] = await deriveSettingsPda(config.smartAccountPda);
69
+ const [spendingLimitPda] = await deriveSpendingLimitPda(config.smartAccountPda, spendingLimitIndex);
70
+ // Serialize: disc + mint(32) + amount(u64 LE) + period(u8) + members_len(u32) + members + destinations_len(u32) + destinations
71
+ const argsSize = 8 + 32 + 8 + 1 + 4 + config.members.length * 32 + 4 + config.destinations.length * 32;
72
+ const data = new Uint8Array(argsSize);
73
+ const view = new DataView(data.buffer);
74
+ const encoder = getAddressEncoder();
75
+ let offset = 0;
76
+ data.set(ADD_SPENDING_LIMIT_DISC, offset);
77
+ offset += 8;
78
+ // Mint
79
+ data.set(encoder.encode(config.mint), offset);
80
+ offset += 32;
81
+ // Amount (u64 LE)
82
+ view.setBigUint64(offset, config.amount, true);
83
+ offset += 8;
84
+ // Period (u8 enum)
85
+ data[offset] = config.period;
86
+ offset += 1;
87
+ // Members
88
+ view.setUint32(offset, config.members.length, true);
89
+ offset += 4;
90
+ for (const member of config.members) {
91
+ data.set(encoder.encode(member), offset);
92
+ offset += 32;
93
+ }
94
+ // Destinations
95
+ view.setUint32(offset, config.destinations.length, true);
96
+ offset += 4;
97
+ for (const dest of config.destinations) {
98
+ data.set(encoder.encode(dest), offset);
99
+ offset += 32;
100
+ }
101
+ return {
102
+ programAddress: SQUADS_PROGRAM_ID,
103
+ accounts: [
104
+ { address: config.smartAccountPda, role: 0 }, // readonly
105
+ { address: settingsPda, role: 0 }, // readonly
106
+ { address: spendingLimitPda, role: 1 }, // writable
107
+ { address: authority, role: 3 }, // writable + signer
108
+ { address: SYSTEM_PROGRAM, role: 0 }, // readonly
109
+ ],
110
+ data,
111
+ };
112
+ }
113
+ /**
114
+ * Build a `useSpendingLimit` instruction.
115
+ * Spends within the limit — no proposal required.
116
+ */
117
+ export async function useSpendingLimitInstruction(params) {
118
+ const [settingsPda] = await deriveSettingsPda(params.smartAccountPda);
119
+ const [spendingLimitPda] = await deriveSpendingLimitPda(params.smartAccountPda, params.spendingLimitIndex);
120
+ // Serialize: disc + amount(u64 LE)
121
+ const data = new Uint8Array(8 + 8);
122
+ const view = new DataView(data.buffer);
123
+ data.set(USE_SPENDING_LIMIT_DISC, 0);
124
+ view.setBigUint64(8, params.amount, true);
125
+ return {
126
+ programAddress: SQUADS_PROGRAM_ID,
127
+ accounts: [
128
+ { address: params.smartAccountPda, role: 0 }, // readonly
129
+ { address: settingsPda, role: 0 }, // readonly
130
+ { address: spendingLimitPda, role: 1 }, // writable
131
+ { address: params.sourceTokenAccount, role: 1 }, // writable
132
+ { address: params.destinationTokenAccount, role: 1 }, // writable
133
+ { address: params.member, role: 2 }, // signer
134
+ { address: params.mint, role: 0 }, // readonly
135
+ { address: TOKEN_PROGRAM, role: 0 }, // readonly
136
+ ],
137
+ data,
138
+ };
139
+ }
140
+ /**
141
+ * Build a `removeSpendingLimitAsAuthority` instruction.
142
+ * Revokes a spending limit from the Smart Account.
143
+ */
144
+ export async function removeSpendingLimitInstruction(params) {
145
+ const [settingsPda] = await deriveSettingsPda(params.smartAccountPda);
146
+ const [spendingLimitPda] = await deriveSpendingLimitPda(params.smartAccountPda, params.spendingLimitIndex);
147
+ const data = new Uint8Array(8);
148
+ data.set(REMOVE_SPENDING_LIMIT_DISC, 0);
149
+ return {
150
+ programAddress: SQUADS_PROGRAM_ID,
151
+ accounts: [
152
+ { address: params.smartAccountPda, role: 0 }, // readonly
153
+ { address: settingsPda, role: 0 }, // readonly
154
+ { address: spendingLimitPda, role: 1 }, // writable (closed)
155
+ { address: params.authority, role: 3 }, // writable + signer
156
+ { address: params.rentCollector, role: 1 }, // writable (receives lamports)
157
+ ],
158
+ data,
159
+ };
160
+ }
161
+ // Re-export for convenience
162
+ export { SpendingLimitPeriod };
163
+ //# sourceMappingURL=instructions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/squads/instructions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { Address } from "@solana/kit";
2
+ import type { SpendingLimitConfig } from "./types.js";
3
+ import { SpendingLimitPeriod } from "./types.js";
4
+ /**
5
+ * Create a spending limit instruction for a Smart Account.
6
+ * Returns the instruction — caller is responsible for signing and sending.
7
+ */
8
+ export declare function createSpendingLimit(config: SpendingLimitConfig, spendingLimitIndex: number, authority: Address): Promise<import("@solana/kit").Instruction<string, readonly (import("@solana/kit").AccountLookupMeta<string, string> | import("@solana/kit").AccountMeta<string>)[]>>;
9
+ /**
10
+ * Check if a spending limit account exists on-chain and fetch its state.
11
+ * Returns null if the account doesn't exist.
12
+ */
13
+ export declare function checkSpendingLimit(smartAccountPda: Address, spendingLimitIndex: number, rpcUrl: string): Promise<{
14
+ exists: boolean;
15
+ remainingAmount?: bigint;
16
+ period?: SpendingLimitPeriod;
17
+ lastReset?: bigint;
18
+ } | null>;
19
+ /**
20
+ * Revoke a spending limit from a Smart Account.
21
+ * Returns the instruction — caller is responsible for signing and sending.
22
+ */
23
+ export declare function revokeSpendingLimit(smartAccountPda: Address, spendingLimitIndex: number, authority: Address, rentCollector: Address): Promise<import("@solana/kit").Instruction<string, readonly (import("@solana/kit").AccountLookupMeta<string, string> | import("@solana/kit").AccountMeta<string>)[]>>;
24
+ //# sourceMappingURL=spending.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spending.d.ts","sourceRoot":"","sources":["../../src/squads/spending.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAIjD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,mBAAmB,EAC3B,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,OAAO,wKAGnB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,eAAe,EAAE,OAAO,EACxB,kBAAkB,EAAE,MAAM,EAC1B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IACT,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAAC,CA8BR;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,eAAe,EAAE,OAAO,EACxB,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,OAAO,EAClB,aAAa,EAAE,OAAO,wKAQvB"}
@@ -0,0 +1,54 @@
1
+ import { createSolanaRpc } from "@solana/kit";
2
+ import { SpendingLimitPeriod } from "./types.js";
3
+ import { deriveSpendingLimitPda } from "./accounts.js";
4
+ import { addSpendingLimitInstruction, removeSpendingLimitInstruction } from "./instructions.js";
5
+ /**
6
+ * Create a spending limit instruction for a Smart Account.
7
+ * Returns the instruction — caller is responsible for signing and sending.
8
+ */
9
+ export async function createSpendingLimit(config, spendingLimitIndex, authority) {
10
+ return addSpendingLimitInstruction(config, spendingLimitIndex, authority);
11
+ }
12
+ /**
13
+ * Check if a spending limit account exists on-chain and fetch its state.
14
+ * Returns null if the account doesn't exist.
15
+ */
16
+ export async function checkSpendingLimit(smartAccountPda, spendingLimitIndex, rpcUrl) {
17
+ const rpc = createSolanaRpc(rpcUrl);
18
+ const [spendingLimitPda] = await deriveSpendingLimitPda(smartAccountPda, spendingLimitIndex);
19
+ const accountInfo = await rpc
20
+ .getAccountInfo(spendingLimitPda, { encoding: "base64" })
21
+ .send();
22
+ if (!accountInfo.value) {
23
+ return null;
24
+ }
25
+ // Parse the account data
26
+ // Layout: discriminator(8) + smart_account(32) + mint(32) + amount(8) + remaining_amount(8) + period(1) + last_reset(8) + ...
27
+ const data = Buffer.from(accountInfo.value.data[0], "base64");
28
+ if (data.length < 89) {
29
+ return null;
30
+ }
31
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
32
+ const remainingAmount = view.getBigUint64(80, true); // offset 8+32+32+8 = 80
33
+ const period = data[88]; // offset 80+8 = 88
34
+ const lastReset = view.getBigUint64(89, true); // offset 88+1 = 89
35
+ return {
36
+ exists: true,
37
+ remainingAmount,
38
+ period,
39
+ lastReset,
40
+ };
41
+ }
42
+ /**
43
+ * Revoke a spending limit from a Smart Account.
44
+ * Returns the instruction — caller is responsible for signing and sending.
45
+ */
46
+ export async function revokeSpendingLimit(smartAccountPda, spendingLimitIndex, authority, rentCollector) {
47
+ return removeSpendingLimitInstruction({
48
+ smartAccountPda,
49
+ spendingLimitIndex,
50
+ authority,
51
+ rentCollector,
52
+ });
53
+ }
54
+ //# sourceMappingURL=spending.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spending.js","sourceRoot":"","sources":["../../src/squads/spending.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAEhG;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAA2B,EAC3B,kBAA0B,EAC1B,SAAkB;IAElB,OAAO,2BAA2B,CAAC,MAAM,EAAE,kBAAkB,EAAE,SAAS,CAAC,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,eAAwB,EACxB,kBAA0B,EAC1B,MAAc;IAOd,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,gBAAgB,CAAC,GAAG,MAAM,sBAAsB,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;IAE7F,MAAM,WAAW,GAAG,MAAM,GAAG;SAC1B,cAAc,CAAC,gBAAgB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;SACxD,IAAI,EAAE,CAAC;IAEV,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yBAAyB;IACzB,8HAA8H;IAC9H,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAW,EAAE,QAAQ,CAAC,CAAC;IACxE,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACzE,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,wBAAwB;IAC7E,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAwB,CAAC,CAAC,mBAAmB;IACnE,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,mBAAmB;IAElE,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,eAAe;QACf,MAAM;QACN,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,eAAwB,EACxB,kBAA0B,EAC1B,SAAkB,EAClB,aAAsB;IAEtB,OAAO,8BAA8B,CAAC;QACpC,eAAe;QACf,kBAAkB;QAClB,SAAS;QACT,aAAa;KACd,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { Address } from "@solana/kit";
2
+ /** Squads Smart Account program ID on mainnet/devnet */
3
+ export declare const SQUADS_PROGRAM_ID: Address;
4
+ /** Configuration for creating a spending limit on a Smart Account */
5
+ export interface SpendingLimitConfig {
6
+ /** The Smart Account PDA that owns this spending limit */
7
+ smartAccountPda: Address;
8
+ /** Token mint address (USDC) */
9
+ mint: Address;
10
+ /** Maximum amount allowed per time period (base units) */
11
+ amount: bigint;
12
+ /** Time period for the spending limit */
13
+ period: SpendingLimitPeriod;
14
+ /** Members (agent addresses) authorized to use this spending limit */
15
+ members: Address[];
16
+ /** Destination addresses the agent can send to */
17
+ destinations: Address[];
18
+ }
19
+ /** Time period for spending limit reset */
20
+ export declare enum SpendingLimitPeriod {
21
+ /** One-time allowance — no reset */
22
+ OneTime = 0,
23
+ /** Resets daily */
24
+ Day = 1,
25
+ /** Resets weekly */
26
+ Week = 2,
27
+ /** Resets monthly */
28
+ Month = 3
29
+ }
30
+ /** Configuration for creating a Smart Account */
31
+ export interface SmartAccountConfig {
32
+ /** Creator/authority address */
33
+ creator: Address;
34
+ /** Index for PDA derivation (allows multiple accounts per creator) */
35
+ accountIndex: number;
36
+ /** Signers for the multisig */
37
+ members: Address[];
38
+ /** Number of required signers */
39
+ threshold: number;
40
+ }
41
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/squads/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,EAAoD,OAAO,CAAC;AAE1F,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IAClC,0DAA0D;IAC1D,eAAe,EAAE,OAAO,CAAC;IACzB,gCAAgC;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,sEAAsE;IACtE,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,kDAAkD;IAClD,YAAY,EAAE,OAAO,EAAE,CAAC;CACzB;AAED,2CAA2C;AAC3C,oBAAY,mBAAmB;IAC7B,oCAAoC;IACpC,OAAO,IAAI;IACX,mBAAmB;IACnB,GAAG,IAAI;IACP,oBAAoB;IACpB,IAAI,IAAI;IACR,qBAAqB;IACrB,KAAK,IAAI;CACV;AAED,iDAAiD;AACjD,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,15 @@
1
+ /** Squads Smart Account program ID on mainnet/devnet */
2
+ export const SQUADS_PROGRAM_ID = "SMRTzfY6DfH5ik3TKiyLFfXexV8uSG3d2UksSCYdunG";
3
+ /** Time period for spending limit reset */
4
+ export var SpendingLimitPeriod;
5
+ (function (SpendingLimitPeriod) {
6
+ /** One-time allowance — no reset */
7
+ SpendingLimitPeriod[SpendingLimitPeriod["OneTime"] = 0] = "OneTime";
8
+ /** Resets daily */
9
+ SpendingLimitPeriod[SpendingLimitPeriod["Day"] = 1] = "Day";
10
+ /** Resets weekly */
11
+ SpendingLimitPeriod[SpendingLimitPeriod["Week"] = 2] = "Week";
12
+ /** Resets monthly */
13
+ SpendingLimitPeriod[SpendingLimitPeriod["Month"] = 3] = "Month";
14
+ })(SpendingLimitPeriod || (SpendingLimitPeriod = {}));
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/squads/types.ts"],"names":[],"mappings":"AAEA,wDAAwD;AACxD,MAAM,CAAC,MAAM,iBAAiB,GAAG,6CAAwD,CAAC;AAkB1F,2CAA2C;AAC3C,MAAM,CAAN,IAAY,mBASX;AATD,WAAY,mBAAmB;IAC7B,oCAAoC;IACpC,mEAAW,CAAA;IACX,mBAAmB;IACnB,2DAAO,CAAA;IACP,oBAAoB;IACpB,6DAAQ,CAAA;IACR,qBAAqB;IACrB,+DAAS,CAAA;AACX,CAAC,EATW,mBAAmB,KAAnB,mBAAmB,QAS9B"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@pincerpay/solana",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Solana integration for PincerPay. Kora gasless transactions and Squads smart account support.",
6
+ "license": "MIT",
7
+ "homepage": "https://pincerpay.com",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/ds1/pincerpay.git",
11
+ "directory": "packages/solana"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/ds1/pincerpay/issues"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "keywords": [
20
+ "pincerpay",
21
+ "solana",
22
+ "kora",
23
+ "squads",
24
+ "gasless",
25
+ "usdc",
26
+ "smart-accounts",
27
+ "session-keys"
28
+ ],
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
34
+ "main": "dist/index.js",
35
+ "types": "dist/index.d.ts",
36
+ "exports": {
37
+ ".": {
38
+ "types": "./dist/index.d.ts",
39
+ "import": "./dist/index.js"
40
+ },
41
+ "./kora": {
42
+ "types": "./dist/kora/index.d.ts",
43
+ "import": "./dist/kora/index.js"
44
+ },
45
+ "./squads": {
46
+ "types": "./dist/squads/index.d.ts",
47
+ "import": "./dist/squads/index.js"
48
+ }
49
+ },
50
+ "dependencies": {
51
+ "@solana/kit": "^5.5.1",
52
+ "@x402/svm": "^2.3.0",
53
+ "zod": "^3.24",
54
+ "@pincerpay/core": "0.1.0"
55
+ },
56
+ "devDependencies": {
57
+ "@scure/base": "^1.2.6",
58
+ "typescript": "^5.7"
59
+ },
60
+ "scripts": {
61
+ "build": "tsc",
62
+ "test": "vitest run",
63
+ "typecheck": "tsc --noEmit",
64
+ "clean": "rm -rf dist"
65
+ }
66
+ }