@agent-fuel/sdk 0.1.1 → 0.3.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/CHANGELOG.md +26 -0
- package/README.md +36 -1
- package/dist/cli.cjs +4530 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.js +4528 -0
- package/dist/cli.js.map +1 -0
- package/dist/idl/credit-vault.cjs +475 -1
- package/dist/idl/credit-vault.cjs.map +1 -1
- package/dist/idl/credit-vault.d.cts +477 -1
- package/dist/idl/credit-vault.d.ts +477 -1
- package/dist/idl/credit-vault.js +475 -1
- package/dist/idl/credit-vault.js.map +1 -1
- package/dist/index.cjs +723 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -1
- package/dist/index.d.ts +87 -1
- package/dist/index.js +722 -5
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/dist/index.cjs
CHANGED
|
@@ -63,7 +63,8 @@ function decodeCreditVault(pubkey, raw) {
|
|
|
63
63
|
balance: total_deposited - total_withdrawn - total_spent + total_claimed,
|
|
64
64
|
frozen: raw.frozen,
|
|
65
65
|
created_slot: bnToNum(raw.createdSlot),
|
|
66
|
-
last_active_slot: bnToNum(raw.lastActiveSlot)
|
|
66
|
+
last_active_slot: bnToNum(raw.lastActiveSlot),
|
|
67
|
+
pending_count: bnToNum(raw.pendingCount)
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
70
|
var DEFAULT_PUBKEY = web3_js.PublicKey.default.toBase58();
|
|
@@ -1953,6 +1954,200 @@ var credit_vault_default = {
|
|
|
1953
1954
|
repository: "https://github.com/TODO/agent_fuel"
|
|
1954
1955
|
},
|
|
1955
1956
|
instructions: [
|
|
1957
|
+
{
|
|
1958
|
+
name: "approve_spend",
|
|
1959
|
+
discriminator: [
|
|
1960
|
+
248,
|
|
1961
|
+
201,
|
|
1962
|
+
151,
|
|
1963
|
+
15,
|
|
1964
|
+
28,
|
|
1965
|
+
162,
|
|
1966
|
+
112,
|
|
1967
|
+
90
|
|
1968
|
+
],
|
|
1969
|
+
accounts: [
|
|
1970
|
+
{
|
|
1971
|
+
name: "owner",
|
|
1972
|
+
writable: true,
|
|
1973
|
+
signer: true,
|
|
1974
|
+
relations: [
|
|
1975
|
+
"vault"
|
|
1976
|
+
]
|
|
1977
|
+
},
|
|
1978
|
+
{
|
|
1979
|
+
name: "vault",
|
|
1980
|
+
writable: true,
|
|
1981
|
+
pda: {
|
|
1982
|
+
seeds: [
|
|
1983
|
+
{
|
|
1984
|
+
kind: "const",
|
|
1985
|
+
value: [
|
|
1986
|
+
118,
|
|
1987
|
+
97,
|
|
1988
|
+
117,
|
|
1989
|
+
108,
|
|
1990
|
+
116
|
|
1991
|
+
]
|
|
1992
|
+
},
|
|
1993
|
+
{
|
|
1994
|
+
kind: "account",
|
|
1995
|
+
path: "owner"
|
|
1996
|
+
},
|
|
1997
|
+
{
|
|
1998
|
+
kind: "account",
|
|
1999
|
+
path: "vault.agent",
|
|
2000
|
+
account: "CreditVault"
|
|
2001
|
+
}
|
|
2002
|
+
]
|
|
2003
|
+
}
|
|
2004
|
+
},
|
|
2005
|
+
{
|
|
2006
|
+
name: "policy",
|
|
2007
|
+
writable: true,
|
|
2008
|
+
pda: {
|
|
2009
|
+
seeds: [
|
|
2010
|
+
{
|
|
2011
|
+
kind: "const",
|
|
2012
|
+
value: [
|
|
2013
|
+
112,
|
|
2014
|
+
111,
|
|
2015
|
+
108,
|
|
2016
|
+
105,
|
|
2017
|
+
99,
|
|
2018
|
+
121
|
|
2019
|
+
]
|
|
2020
|
+
},
|
|
2021
|
+
{
|
|
2022
|
+
kind: "account",
|
|
2023
|
+
path: "vault"
|
|
2024
|
+
}
|
|
2025
|
+
]
|
|
2026
|
+
}
|
|
2027
|
+
},
|
|
2028
|
+
{
|
|
2029
|
+
name: "pending_spend",
|
|
2030
|
+
writable: true,
|
|
2031
|
+
pda: {
|
|
2032
|
+
seeds: [
|
|
2033
|
+
{
|
|
2034
|
+
kind: "const",
|
|
2035
|
+
value: [
|
|
2036
|
+
112,
|
|
2037
|
+
101,
|
|
2038
|
+
110,
|
|
2039
|
+
100,
|
|
2040
|
+
105,
|
|
2041
|
+
110,
|
|
2042
|
+
103
|
|
2043
|
+
]
|
|
2044
|
+
},
|
|
2045
|
+
{
|
|
2046
|
+
kind: "account",
|
|
2047
|
+
path: "vault"
|
|
2048
|
+
},
|
|
2049
|
+
{
|
|
2050
|
+
kind: "account",
|
|
2051
|
+
path: "pending_spend.nonce",
|
|
2052
|
+
account: "PendingSpend"
|
|
2053
|
+
}
|
|
2054
|
+
]
|
|
2055
|
+
}
|
|
2056
|
+
},
|
|
2057
|
+
{
|
|
2058
|
+
name: "vault_token_account",
|
|
2059
|
+
writable: true
|
|
2060
|
+
},
|
|
2061
|
+
{
|
|
2062
|
+
name: "service_token_account",
|
|
2063
|
+
writable: true
|
|
2064
|
+
},
|
|
2065
|
+
{
|
|
2066
|
+
name: "token_program",
|
|
2067
|
+
address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
|
|
2068
|
+
}
|
|
2069
|
+
],
|
|
2070
|
+
args: []
|
|
2071
|
+
},
|
|
2072
|
+
{
|
|
2073
|
+
name: "cancel_spend",
|
|
2074
|
+
discriminator: [
|
|
2075
|
+
122,
|
|
2076
|
+
254,
|
|
2077
|
+
101,
|
|
2078
|
+
132,
|
|
2079
|
+
241,
|
|
2080
|
+
232,
|
|
2081
|
+
205,
|
|
2082
|
+
179
|
|
2083
|
+
],
|
|
2084
|
+
accounts: [
|
|
2085
|
+
{
|
|
2086
|
+
name: "owner",
|
|
2087
|
+
writable: true,
|
|
2088
|
+
signer: true,
|
|
2089
|
+
relations: [
|
|
2090
|
+
"vault"
|
|
2091
|
+
]
|
|
2092
|
+
},
|
|
2093
|
+
{
|
|
2094
|
+
name: "vault",
|
|
2095
|
+
pda: {
|
|
2096
|
+
seeds: [
|
|
2097
|
+
{
|
|
2098
|
+
kind: "const",
|
|
2099
|
+
value: [
|
|
2100
|
+
118,
|
|
2101
|
+
97,
|
|
2102
|
+
117,
|
|
2103
|
+
108,
|
|
2104
|
+
116
|
|
2105
|
+
]
|
|
2106
|
+
},
|
|
2107
|
+
{
|
|
2108
|
+
kind: "account",
|
|
2109
|
+
path: "owner"
|
|
2110
|
+
},
|
|
2111
|
+
{
|
|
2112
|
+
kind: "account",
|
|
2113
|
+
path: "vault.agent",
|
|
2114
|
+
account: "CreditVault"
|
|
2115
|
+
}
|
|
2116
|
+
]
|
|
2117
|
+
}
|
|
2118
|
+
},
|
|
2119
|
+
{
|
|
2120
|
+
name: "pending_spend",
|
|
2121
|
+
writable: true,
|
|
2122
|
+
pda: {
|
|
2123
|
+
seeds: [
|
|
2124
|
+
{
|
|
2125
|
+
kind: "const",
|
|
2126
|
+
value: [
|
|
2127
|
+
112,
|
|
2128
|
+
101,
|
|
2129
|
+
110,
|
|
2130
|
+
100,
|
|
2131
|
+
105,
|
|
2132
|
+
110,
|
|
2133
|
+
103
|
|
2134
|
+
]
|
|
2135
|
+
},
|
|
2136
|
+
{
|
|
2137
|
+
kind: "account",
|
|
2138
|
+
path: "vault"
|
|
2139
|
+
},
|
|
2140
|
+
{
|
|
2141
|
+
kind: "account",
|
|
2142
|
+
path: "pending_spend.nonce",
|
|
2143
|
+
account: "PendingSpend"
|
|
2144
|
+
}
|
|
2145
|
+
]
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
],
|
|
2149
|
+
args: []
|
|
2150
|
+
},
|
|
1956
2151
|
{
|
|
1957
2152
|
name: "claim",
|
|
1958
2153
|
discriminator: [
|
|
@@ -2359,6 +2554,104 @@ var credit_vault_default = {
|
|
|
2359
2554
|
],
|
|
2360
2555
|
args: []
|
|
2361
2556
|
},
|
|
2557
|
+
{
|
|
2558
|
+
name: "request_spend",
|
|
2559
|
+
discriminator: [
|
|
2560
|
+
127,
|
|
2561
|
+
12,
|
|
2562
|
+
23,
|
|
2563
|
+
75,
|
|
2564
|
+
137,
|
|
2565
|
+
178,
|
|
2566
|
+
148,
|
|
2567
|
+
71
|
|
2568
|
+
],
|
|
2569
|
+
accounts: [
|
|
2570
|
+
{
|
|
2571
|
+
name: "agent",
|
|
2572
|
+
writable: true,
|
|
2573
|
+
signer: true,
|
|
2574
|
+
relations: [
|
|
2575
|
+
"vault"
|
|
2576
|
+
]
|
|
2577
|
+
},
|
|
2578
|
+
{
|
|
2579
|
+
name: "vault",
|
|
2580
|
+
writable: true,
|
|
2581
|
+
pda: {
|
|
2582
|
+
seeds: [
|
|
2583
|
+
{
|
|
2584
|
+
kind: "const",
|
|
2585
|
+
value: [
|
|
2586
|
+
118,
|
|
2587
|
+
97,
|
|
2588
|
+
117,
|
|
2589
|
+
108,
|
|
2590
|
+
116
|
|
2591
|
+
]
|
|
2592
|
+
},
|
|
2593
|
+
{
|
|
2594
|
+
kind: "account",
|
|
2595
|
+
path: "vault.owner",
|
|
2596
|
+
account: "CreditVault"
|
|
2597
|
+
},
|
|
2598
|
+
{
|
|
2599
|
+
kind: "account",
|
|
2600
|
+
path: "vault.agent",
|
|
2601
|
+
account: "CreditVault"
|
|
2602
|
+
}
|
|
2603
|
+
]
|
|
2604
|
+
}
|
|
2605
|
+
},
|
|
2606
|
+
{
|
|
2607
|
+
name: "service_token_account",
|
|
2608
|
+
docs: [
|
|
2609
|
+
"The recipient token account. We only need it for its `owner` field",
|
|
2610
|
+
"(the service pubkey we record in PendingSpend); mint constraint is",
|
|
2611
|
+
"belt-and-suspenders since `approve_spend` re-checks both."
|
|
2612
|
+
]
|
|
2613
|
+
},
|
|
2614
|
+
{
|
|
2615
|
+
name: "pending_spend",
|
|
2616
|
+
writable: true,
|
|
2617
|
+
pda: {
|
|
2618
|
+
seeds: [
|
|
2619
|
+
{
|
|
2620
|
+
kind: "const",
|
|
2621
|
+
value: [
|
|
2622
|
+
112,
|
|
2623
|
+
101,
|
|
2624
|
+
110,
|
|
2625
|
+
100,
|
|
2626
|
+
105,
|
|
2627
|
+
110,
|
|
2628
|
+
103
|
|
2629
|
+
]
|
|
2630
|
+
},
|
|
2631
|
+
{
|
|
2632
|
+
kind: "account",
|
|
2633
|
+
path: "vault"
|
|
2634
|
+
},
|
|
2635
|
+
{
|
|
2636
|
+
kind: "account",
|
|
2637
|
+
path: "vault.pending_count",
|
|
2638
|
+
account: "CreditVault"
|
|
2639
|
+
}
|
|
2640
|
+
]
|
|
2641
|
+
}
|
|
2642
|
+
},
|
|
2643
|
+
{
|
|
2644
|
+
name: "system_program",
|
|
2645
|
+
address: "11111111111111111111111111111111"
|
|
2646
|
+
}
|
|
2647
|
+
],
|
|
2648
|
+
args: [
|
|
2649
|
+
{
|
|
2650
|
+
name: "amount_usdc",
|
|
2651
|
+
type: "u64"
|
|
2652
|
+
}
|
|
2653
|
+
]
|
|
2654
|
+
},
|
|
2362
2655
|
{
|
|
2363
2656
|
name: "spend",
|
|
2364
2657
|
discriminator: [
|
|
@@ -2684,6 +2977,19 @@ var credit_vault_default = {
|
|
|
2684
2977
|
70
|
|
2685
2978
|
]
|
|
2686
2979
|
},
|
|
2980
|
+
{
|
|
2981
|
+
name: "PendingSpend",
|
|
2982
|
+
discriminator: [
|
|
2983
|
+
193,
|
|
2984
|
+
205,
|
|
2985
|
+
85,
|
|
2986
|
+
66,
|
|
2987
|
+
25,
|
|
2988
|
+
3,
|
|
2989
|
+
67,
|
|
2990
|
+
134
|
|
2991
|
+
]
|
|
2992
|
+
},
|
|
2687
2993
|
{
|
|
2688
2994
|
name: "SpendPolicy",
|
|
2689
2995
|
discriminator: [
|
|
@@ -2738,6 +3044,32 @@ var credit_vault_default = {
|
|
|
2738
3044
|
161
|
|
2739
3045
|
]
|
|
2740
3046
|
},
|
|
3047
|
+
{
|
|
3048
|
+
name: "SpendRejected",
|
|
3049
|
+
discriminator: [
|
|
3050
|
+
22,
|
|
3051
|
+
233,
|
|
3052
|
+
208,
|
|
3053
|
+
109,
|
|
3054
|
+
202,
|
|
3055
|
+
231,
|
|
3056
|
+
175,
|
|
3057
|
+
22
|
|
3058
|
+
]
|
|
3059
|
+
},
|
|
3060
|
+
{
|
|
3061
|
+
name: "SpendRequested",
|
|
3062
|
+
discriminator: [
|
|
3063
|
+
144,
|
|
3064
|
+
207,
|
|
3065
|
+
254,
|
|
3066
|
+
247,
|
|
3067
|
+
81,
|
|
3068
|
+
146,
|
|
3069
|
+
84,
|
|
3070
|
+
87
|
|
3071
|
+
]
|
|
3072
|
+
},
|
|
2741
3073
|
{
|
|
2742
3074
|
name: "Spent",
|
|
2743
3075
|
discriminator: [
|
|
@@ -2854,6 +3186,16 @@ var credit_vault_default = {
|
|
|
2854
3186
|
code: 6009,
|
|
2855
3187
|
name: "PostPayDisabled",
|
|
2856
3188
|
msg: "Post-pay claims are disabled for this vault"
|
|
3189
|
+
},
|
|
3190
|
+
{
|
|
3191
|
+
code: 6010,
|
|
3192
|
+
name: "PendingSpendVaultMismatch",
|
|
3193
|
+
msg: "Pending spend belongs to a different vault"
|
|
3194
|
+
},
|
|
3195
|
+
{
|
|
3196
|
+
code: 6011,
|
|
3197
|
+
name: "PendingNonceOverflow",
|
|
3198
|
+
msg: "Pending spend counter would overflow"
|
|
2857
3199
|
}
|
|
2858
3200
|
],
|
|
2859
3201
|
types: [
|
|
@@ -2942,12 +3284,22 @@ var credit_vault_default = {
|
|
|
2942
3284
|
name: "bump",
|
|
2943
3285
|
type: "u8"
|
|
2944
3286
|
},
|
|
3287
|
+
{
|
|
3288
|
+
name: "pending_count",
|
|
3289
|
+
docs: [
|
|
3290
|
+
"Monotonic counter used as a PDA seed for PendingSpend accounts so",
|
|
3291
|
+
"every approval request gets a unique deterministic address.",
|
|
3292
|
+
"Borrowed 8 bytes from the original 64-byte padding so the account",
|
|
3293
|
+
"size stays at `ACCOUNT_SIZE` and existing vaults need no migration."
|
|
3294
|
+
],
|
|
3295
|
+
type: "u64"
|
|
3296
|
+
},
|
|
2945
3297
|
{
|
|
2946
3298
|
name: "_padding",
|
|
2947
3299
|
type: {
|
|
2948
3300
|
array: [
|
|
2949
3301
|
"u8",
|
|
2950
|
-
|
|
3302
|
+
56
|
|
2951
3303
|
]
|
|
2952
3304
|
}
|
|
2953
3305
|
}
|
|
@@ -2982,6 +3334,65 @@ var credit_vault_default = {
|
|
|
2982
3334
|
]
|
|
2983
3335
|
}
|
|
2984
3336
|
},
|
|
3337
|
+
{
|
|
3338
|
+
name: "PendingSpend",
|
|
3339
|
+
docs: [
|
|
3340
|
+
"A spend request that exceeded one of the policy's rate limits. The agent",
|
|
3341
|
+
"creates this account by calling `request_spend`; the owner reviews from",
|
|
3342
|
+
"the mobile Alerts tab and either calls `approve_spend` (PDA-signed CPI",
|
|
3343
|
+
"transfer, account closed) or `cancel_spend` (account closed, no transfer).",
|
|
3344
|
+
"",
|
|
3345
|
+
'Seeded by `["pending", vault, nonce_le]` where `nonce` is the value of',
|
|
3346
|
+
"`vault.pending_count` at request time, so each request has a unique",
|
|
3347
|
+
"deterministic address that both the agent and the owner can derive."
|
|
3348
|
+
],
|
|
3349
|
+
type: {
|
|
3350
|
+
kind: "struct",
|
|
3351
|
+
fields: [
|
|
3352
|
+
{
|
|
3353
|
+
name: "vault",
|
|
3354
|
+
type: "pubkey"
|
|
3355
|
+
},
|
|
3356
|
+
{
|
|
3357
|
+
name: "agent",
|
|
3358
|
+
type: "pubkey"
|
|
3359
|
+
},
|
|
3360
|
+
{
|
|
3361
|
+
name: "service",
|
|
3362
|
+
docs: [
|
|
3363
|
+
"Owner of the destination token account (mirrors how `Spent` records",
|
|
3364
|
+
"service: `service_token_account.owner`)."
|
|
3365
|
+
],
|
|
3366
|
+
type: "pubkey"
|
|
3367
|
+
},
|
|
3368
|
+
{
|
|
3369
|
+
name: "amount_usdc",
|
|
3370
|
+
type: "u64"
|
|
3371
|
+
},
|
|
3372
|
+
{
|
|
3373
|
+
name: "requested_slot",
|
|
3374
|
+
type: "u64"
|
|
3375
|
+
},
|
|
3376
|
+
{
|
|
3377
|
+
name: "nonce",
|
|
3378
|
+
type: "u64"
|
|
3379
|
+
},
|
|
3380
|
+
{
|
|
3381
|
+
name: "bump",
|
|
3382
|
+
type: "u8"
|
|
3383
|
+
},
|
|
3384
|
+
{
|
|
3385
|
+
name: "_padding",
|
|
3386
|
+
type: {
|
|
3387
|
+
array: [
|
|
3388
|
+
"u8",
|
|
3389
|
+
31
|
|
3390
|
+
]
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
]
|
|
3394
|
+
}
|
|
3395
|
+
},
|
|
2985
3396
|
{
|
|
2986
3397
|
name: "PolicyUpdated",
|
|
2987
3398
|
type: {
|
|
@@ -3085,6 +3496,70 @@ var credit_vault_default = {
|
|
|
3085
3496
|
]
|
|
3086
3497
|
}
|
|
3087
3498
|
},
|
|
3499
|
+
{
|
|
3500
|
+
name: "SpendRejected",
|
|
3501
|
+
type: {
|
|
3502
|
+
kind: "struct",
|
|
3503
|
+
fields: [
|
|
3504
|
+
{
|
|
3505
|
+
name: "vault",
|
|
3506
|
+
type: "pubkey"
|
|
3507
|
+
},
|
|
3508
|
+
{
|
|
3509
|
+
name: "owner",
|
|
3510
|
+
type: "pubkey"
|
|
3511
|
+
},
|
|
3512
|
+
{
|
|
3513
|
+
name: "pending_spend",
|
|
3514
|
+
type: "pubkey"
|
|
3515
|
+
},
|
|
3516
|
+
{
|
|
3517
|
+
name: "nonce",
|
|
3518
|
+
type: "u64"
|
|
3519
|
+
},
|
|
3520
|
+
{
|
|
3521
|
+
name: "slot",
|
|
3522
|
+
type: "u64"
|
|
3523
|
+
}
|
|
3524
|
+
]
|
|
3525
|
+
}
|
|
3526
|
+
},
|
|
3527
|
+
{
|
|
3528
|
+
name: "SpendRequested",
|
|
3529
|
+
type: {
|
|
3530
|
+
kind: "struct",
|
|
3531
|
+
fields: [
|
|
3532
|
+
{
|
|
3533
|
+
name: "vault",
|
|
3534
|
+
type: "pubkey"
|
|
3535
|
+
},
|
|
3536
|
+
{
|
|
3537
|
+
name: "agent",
|
|
3538
|
+
type: "pubkey"
|
|
3539
|
+
},
|
|
3540
|
+
{
|
|
3541
|
+
name: "service",
|
|
3542
|
+
type: "pubkey"
|
|
3543
|
+
},
|
|
3544
|
+
{
|
|
3545
|
+
name: "pending_spend",
|
|
3546
|
+
type: "pubkey"
|
|
3547
|
+
},
|
|
3548
|
+
{
|
|
3549
|
+
name: "amount_usdc",
|
|
3550
|
+
type: "u64"
|
|
3551
|
+
},
|
|
3552
|
+
{
|
|
3553
|
+
name: "nonce",
|
|
3554
|
+
type: "u64"
|
|
3555
|
+
},
|
|
3556
|
+
{
|
|
3557
|
+
name: "slot",
|
|
3558
|
+
type: "u64"
|
|
3559
|
+
}
|
|
3560
|
+
]
|
|
3561
|
+
}
|
|
3562
|
+
},
|
|
3088
3563
|
{
|
|
3089
3564
|
name: "Spent",
|
|
3090
3565
|
type: {
|
|
@@ -3269,6 +3744,15 @@ function agentServiceLinkPda(agentProfile, serviceRegistry) {
|
|
|
3269
3744
|
);
|
|
3270
3745
|
return pda;
|
|
3271
3746
|
}
|
|
3747
|
+
function pendingSpendPda(vault, nonce) {
|
|
3748
|
+
const nonceBuf = Buffer.alloc(8);
|
|
3749
|
+
nonceBuf.writeBigUInt64LE(typeof nonce === "bigint" ? nonce : BigInt(nonce));
|
|
3750
|
+
const [pda] = web3_js.PublicKey.findProgramAddressSync(
|
|
3751
|
+
[Buffer.from("pending"), toPubkey(vault).toBuffer(), nonceBuf],
|
|
3752
|
+
PROGRAM_IDS.creditVault
|
|
3753
|
+
);
|
|
3754
|
+
return pda;
|
|
3755
|
+
}
|
|
3272
3756
|
function receiptUsedPda(receiptHash) {
|
|
3273
3757
|
if (receiptHash.length !== 32) {
|
|
3274
3758
|
throw new Error(`receiptUsedPda expects a 32-byte hash, got ${receiptHash.length}`);
|
|
@@ -3289,6 +3773,207 @@ function reputationProgram(provider) {
|
|
|
3289
3773
|
return new anchor.Program(reputation_default, provider);
|
|
3290
3774
|
}
|
|
3291
3775
|
|
|
3776
|
+
// src/pay.ts
|
|
3777
|
+
async function pay(args) {
|
|
3778
|
+
const { agent, service, connection, amountUsdc } = args;
|
|
3779
|
+
const owner = toPubkey(args.owner);
|
|
3780
|
+
if (amountUsdc <= 0) {
|
|
3781
|
+
throw new ZeroAmountError();
|
|
3782
|
+
}
|
|
3783
|
+
if (args.receiptHash.length !== 32) {
|
|
3784
|
+
throw new Error(
|
|
3785
|
+
`pay: receiptHash must be 32 bytes, got ${args.receiptHash.length}`
|
|
3786
|
+
);
|
|
3787
|
+
}
|
|
3788
|
+
const vaultAddr = vaultPda(owner, agent.publicKey);
|
|
3789
|
+
const policyAddr = policyPda(vaultAddr);
|
|
3790
|
+
const provider = buildProvider(connection, agent);
|
|
3791
|
+
const cv = creditVaultProgram(provider);
|
|
3792
|
+
const rep = reputationProgram(provider);
|
|
3793
|
+
const [rawVault, rawPolicy, currentSlot] = await Promise.all([
|
|
3794
|
+
cv.account.creditVault.fetchNullable(vaultAddr),
|
|
3795
|
+
cv.account.spendPolicy.fetchNullable(policyAddr),
|
|
3796
|
+
connection.getSlot()
|
|
3797
|
+
]);
|
|
3798
|
+
if (!rawVault) throw new AccountNotFoundError(vaultAddr.toBase58());
|
|
3799
|
+
if (!rawPolicy) throw new AccountNotFoundError(policyAddr.toBase58());
|
|
3800
|
+
const vault = decodeCreditVault(vaultAddr, rawVault);
|
|
3801
|
+
const policy = decodeSpendPolicy(policyAddr, rawPolicy);
|
|
3802
|
+
guardSpend({
|
|
3803
|
+
vault,
|
|
3804
|
+
policy,
|
|
3805
|
+
service: service.publicKey,
|
|
3806
|
+
amountUsdc,
|
|
3807
|
+
currentSlot
|
|
3808
|
+
});
|
|
3809
|
+
const serviceTokenAccount = getAssociatedTokenAddress(
|
|
3810
|
+
vault.usdc_mint,
|
|
3811
|
+
service.publicKey
|
|
3812
|
+
);
|
|
3813
|
+
const createAtaIx = createAssociatedTokenAccountIdempotentInstruction(
|
|
3814
|
+
agent.publicKey,
|
|
3815
|
+
serviceTokenAccount,
|
|
3816
|
+
service.publicKey,
|
|
3817
|
+
vault.usdc_mint
|
|
3818
|
+
);
|
|
3819
|
+
const agentProfile = agentProfilePda(agent.publicKey);
|
|
3820
|
+
const serviceRegistry = serviceRegistryPda(service.publicKey);
|
|
3821
|
+
const link = agentServiceLinkPda(agentProfile, serviceRegistry);
|
|
3822
|
+
const receipt = receiptUsedPda(args.receiptHash);
|
|
3823
|
+
const spendBuilder = cv.methods.spend(new anchor.BN(amountUsdc)).accounts({
|
|
3824
|
+
agent: agent.publicKey,
|
|
3825
|
+
vault: vaultAddr,
|
|
3826
|
+
policy: policyAddr,
|
|
3827
|
+
vaultTokenAccount: vault.vault_token_account,
|
|
3828
|
+
serviceTokenAccount,
|
|
3829
|
+
tokenProgram: TOKEN_PROGRAM_ID
|
|
3830
|
+
});
|
|
3831
|
+
const recordBuilder = rep.methods.recordPayment(new anchor.BN(amountUsdc), args.receiptHash).accounts({
|
|
3832
|
+
service: service.publicKey,
|
|
3833
|
+
agentProfile,
|
|
3834
|
+
serviceRegistry,
|
|
3835
|
+
agentServiceLink: link,
|
|
3836
|
+
receiptUsed: receipt,
|
|
3837
|
+
systemProgram: web3_js.SystemProgram.programId
|
|
3838
|
+
});
|
|
3839
|
+
const spendIx = await spendBuilder.instruction();
|
|
3840
|
+
const recordIx = await recordBuilder.instruction();
|
|
3841
|
+
const tx = new web3_js.Transaction().add(createAtaIx, spendIx, recordIx);
|
|
3842
|
+
try {
|
|
3843
|
+
const signature = await web3_js.sendAndConfirmTransaction(
|
|
3844
|
+
connection,
|
|
3845
|
+
tx,
|
|
3846
|
+
[agent, service],
|
|
3847
|
+
{ commitment: "confirmed" }
|
|
3848
|
+
);
|
|
3849
|
+
return { signature };
|
|
3850
|
+
} catch (err) {
|
|
3851
|
+
throw mapPayError(err, {
|
|
3852
|
+
service: service.publicKey,
|
|
3853
|
+
amountUsdc,
|
|
3854
|
+
vault,
|
|
3855
|
+
policy,
|
|
3856
|
+
receiptHash: args.receiptHash
|
|
3857
|
+
});
|
|
3858
|
+
}
|
|
3859
|
+
}
|
|
3860
|
+
function mapPayError(err, ctx) {
|
|
3861
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3862
|
+
if (/already in use/i.test(message)) {
|
|
3863
|
+
return new ReceiptAlreadyRecordedError(ctx.receiptHash);
|
|
3864
|
+
}
|
|
3865
|
+
if (!(err instanceof anchor.AnchorError)) return err;
|
|
3866
|
+
switch (err.error.errorCode.number) {
|
|
3867
|
+
case 6001:
|
|
3868
|
+
return new ZeroAmountError();
|
|
3869
|
+
case 6002:
|
|
3870
|
+
return new VaultFrozenError();
|
|
3871
|
+
case 6003:
|
|
3872
|
+
return new NotWhitelistedError(ctx.service.toBase58());
|
|
3873
|
+
case 6004:
|
|
3874
|
+
return new PerTxLimitExceededError(ctx.amountUsdc, ctx.policy.per_tx_limit_usdc);
|
|
3875
|
+
case 6005:
|
|
3876
|
+
return new HourlyLimitExceededError(
|
|
3877
|
+
ctx.amountUsdc,
|
|
3878
|
+
ctx.policy.hourly_window_spent_usdc,
|
|
3879
|
+
ctx.policy.hourly_limit_usdc
|
|
3880
|
+
);
|
|
3881
|
+
case 6006:
|
|
3882
|
+
return new LifetimeLimitExceededError(
|
|
3883
|
+
ctx.amountUsdc,
|
|
3884
|
+
ctx.vault.total_spent,
|
|
3885
|
+
ctx.policy.lifetime_limit_usdc
|
|
3886
|
+
);
|
|
3887
|
+
// Reputation errors:
|
|
3888
|
+
case 6e3:
|
|
3889
|
+
return new RecordPaymentError("counter overflow on chain");
|
|
3890
|
+
case 6011:
|
|
3891
|
+
return new ServiceInactiveError(ctx.service.toBase58());
|
|
3892
|
+
default:
|
|
3893
|
+
return err;
|
|
3894
|
+
}
|
|
3895
|
+
}
|
|
3896
|
+
async function requestSpend(args) {
|
|
3897
|
+
const { agent, connection, amountUsdc } = args;
|
|
3898
|
+
const owner = toPubkey(args.owner);
|
|
3899
|
+
const service = toPubkey(args.service);
|
|
3900
|
+
if (amountUsdc <= 0) {
|
|
3901
|
+
throw new Error("requestSpend: amountUsdc must be > 0");
|
|
3902
|
+
}
|
|
3903
|
+
const vaultAddr = vaultPda(owner, agent.publicKey);
|
|
3904
|
+
const provider = buildProvider(connection, agent);
|
|
3905
|
+
const cv = creditVaultProgram(provider);
|
|
3906
|
+
const rawVault = await cv.account.creditVault.fetchNullable(vaultAddr);
|
|
3907
|
+
if (!rawVault) throw new AccountNotFoundError(vaultAddr.toBase58());
|
|
3908
|
+
const vault = decodeCreditVault(vaultAddr, rawVault);
|
|
3909
|
+
const nonce = vault.pending_count;
|
|
3910
|
+
const pendingSpend = pendingSpendPda(vaultAddr, nonce);
|
|
3911
|
+
const serviceTokenAccount = getAssociatedTokenAddress(
|
|
3912
|
+
vault.usdc_mint,
|
|
3913
|
+
service
|
|
3914
|
+
);
|
|
3915
|
+
const signature = await cv.methods.requestSpend(new anchor.BN(amountUsdc)).accounts({
|
|
3916
|
+
agent: agent.publicKey,
|
|
3917
|
+
vault: vaultAddr,
|
|
3918
|
+
serviceTokenAccount,
|
|
3919
|
+
pendingSpend,
|
|
3920
|
+
systemProgram: web3_js.SystemProgram.programId
|
|
3921
|
+
}).signers([agent]).rpc();
|
|
3922
|
+
return { signature, pendingSpend, nonce };
|
|
3923
|
+
}
|
|
3924
|
+
var NAME_BYTES = 32;
|
|
3925
|
+
var URI_BYTES = 128;
|
|
3926
|
+
async function registerService(args) {
|
|
3927
|
+
const { sponsor, service, connection } = args;
|
|
3928
|
+
if (args.name.length === 0) {
|
|
3929
|
+
throw new Error("registerService: name must not be empty");
|
|
3930
|
+
}
|
|
3931
|
+
if (Buffer.byteLength(args.name, "utf8") > NAME_BYTES) {
|
|
3932
|
+
throw new Error(
|
|
3933
|
+
`registerService: name exceeds ${NAME_BYTES} bytes (got ${Buffer.byteLength(args.name, "utf8")})`
|
|
3934
|
+
);
|
|
3935
|
+
}
|
|
3936
|
+
const uri = args.serviceUri ?? "";
|
|
3937
|
+
if (Buffer.byteLength(uri, "utf8") > URI_BYTES) {
|
|
3938
|
+
throw new Error(
|
|
3939
|
+
`registerService: serviceUri exceeds ${URI_BYTES} bytes (got ${Buffer.byteLength(uri, "utf8")})`
|
|
3940
|
+
);
|
|
3941
|
+
}
|
|
3942
|
+
const registry = serviceRegistryPda(service.publicKey);
|
|
3943
|
+
const provider = buildProvider(connection, sponsor);
|
|
3944
|
+
const rep = reputationProgram(provider);
|
|
3945
|
+
const signature = await rep.methods.registerService(
|
|
3946
|
+
packFixed(args.name, NAME_BYTES),
|
|
3947
|
+
categoryArg(args.category),
|
|
3948
|
+
packFixed(uri, URI_BYTES)
|
|
3949
|
+
).accounts({
|
|
3950
|
+
sponsor: sponsor.publicKey,
|
|
3951
|
+
service: service.publicKey,
|
|
3952
|
+
serviceRegistry: registry,
|
|
3953
|
+
systemProgram: web3_js.SystemProgram.programId
|
|
3954
|
+
}).signers([sponsor, service]).rpc();
|
|
3955
|
+
return { signature };
|
|
3956
|
+
}
|
|
3957
|
+
function packFixed(s, length) {
|
|
3958
|
+
const buf = Buffer.alloc(length);
|
|
3959
|
+
buf.write(s, 0, "utf8");
|
|
3960
|
+
return Array.from(buf);
|
|
3961
|
+
}
|
|
3962
|
+
function categoryArg(c) {
|
|
3963
|
+
switch (c) {
|
|
3964
|
+
case "DataFeed":
|
|
3965
|
+
return { dataFeed: {} };
|
|
3966
|
+
case "Compute":
|
|
3967
|
+
return { compute: {} };
|
|
3968
|
+
case "Swap":
|
|
3969
|
+
return { swap: {} };
|
|
3970
|
+
case "Rpc":
|
|
3971
|
+
return { rpc: {} };
|
|
3972
|
+
case "Other":
|
|
3973
|
+
return { other: {} };
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
|
|
3292
3977
|
// src/client.ts
|
|
3293
3978
|
var DEFAULT_API_BASE = "http://localhost:8080";
|
|
3294
3979
|
var AgentFuel = class {
|
|
@@ -3387,6 +4072,38 @@ var AgentFuel = class {
|
|
|
3387
4072
|
throw mapSpendError(err, { service, amountUsdc, vault, policy });
|
|
3388
4073
|
}
|
|
3389
4074
|
}
|
|
4075
|
+
/// Atomic spend + record_payment in one transaction. Use this instead
|
|
4076
|
+
/// of `spend()` + `recordPayment()` when you want the vault burn and
|
|
4077
|
+
/// the reputation accrual to be all-or-nothing. The service keypair
|
|
4078
|
+
/// co-signs.
|
|
4079
|
+
async pay(args) {
|
|
4080
|
+
return pay({
|
|
4081
|
+
agent: this.agent,
|
|
4082
|
+
owner: this.resolveOwner(args.owner),
|
|
4083
|
+
service: args.service,
|
|
4084
|
+
amountUsdc: args.amountUsdc,
|
|
4085
|
+
receiptHash: args.receiptHash,
|
|
4086
|
+
connection: this.connection
|
|
4087
|
+
});
|
|
4088
|
+
}
|
|
4089
|
+
/// Submit an over-limit spend request the owner can approve from the
|
|
4090
|
+
/// mobile app. Returns the `pendingSpend` PDA so the bot can poll for
|
|
4091
|
+
/// resolution.
|
|
4092
|
+
async requestSpend(args) {
|
|
4093
|
+
return requestSpend({
|
|
4094
|
+
agent: this.agent,
|
|
4095
|
+
owner: this.resolveOwner(args.owner),
|
|
4096
|
+
service: args.service,
|
|
4097
|
+
amountUsdc: args.amountUsdc,
|
|
4098
|
+
connection: this.connection
|
|
4099
|
+
});
|
|
4100
|
+
}
|
|
4101
|
+
/// Register a service on chain. The `sponsor` (typically `this.agent`'s
|
|
4102
|
+
/// owner wallet) pays rent; the `service` keypair is the long-lived
|
|
4103
|
+
/// identity that will co-sign every future `record_payment`.
|
|
4104
|
+
async registerService(args) {
|
|
4105
|
+
return registerService({ ...args, connection: this.connection });
|
|
4106
|
+
}
|
|
3390
4107
|
/// Triggers an on-chain recomputation of the agent's reputation score.
|
|
3391
4108
|
/// Permissionless — any signer can call it; we use the agent itself since
|
|
3392
4109
|
/// the SDK already has its keypair available and it already pays tx fees
|
|
@@ -3606,10 +4323,14 @@ exports.agentProfilePda = agentProfilePda;
|
|
|
3606
4323
|
exports.agentServiceLinkPda = agentServiceLinkPda;
|
|
3607
4324
|
exports.createAssociatedTokenAccountIdempotentInstruction = createAssociatedTokenAccountIdempotentInstruction;
|
|
3608
4325
|
exports.getAssociatedTokenAddress = getAssociatedTokenAddress;
|
|
4326
|
+
exports.pay = pay;
|
|
3609
4327
|
exports.paymentRequired = paymentRequired;
|
|
4328
|
+
exports.pendingSpendPda = pendingSpendPda;
|
|
3610
4329
|
exports.policyPda = policyPda;
|
|
3611
4330
|
exports.receiptUsedPda = receiptUsedPda;
|
|
3612
4331
|
exports.recordPayment = recordPayment;
|
|
4332
|
+
exports.registerService = registerService;
|
|
4333
|
+
exports.requestSpend = requestSpend;
|
|
3613
4334
|
exports.serviceRegistryPda = serviceRegistryPda;
|
|
3614
4335
|
exports.subscribeService = subscribeService;
|
|
3615
4336
|
exports.subscribeVault = subscribeVault;
|