Skip to content

Commit e4ebffc

Browse files
authored
Merge pull request #5 from BowTiedRadone/feat/sbtc-transfer-many
Add STX and sBTC transfer-many extensions
2 parents 47ae732 + 446eea0 commit e4ebffc

16 files changed

Lines changed: 52679 additions & 16860 deletions

.github/workflows/tests.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ jobs:
2929
pnpm generate
3030
pnpm test -- --coverage
3131
32-
- name: Commit coverage report
32+
- name: Normalize lcov.info paths and commit coverage report
3333
if: github.event_name == 'push'
3434
run: |
35+
# Convert absolute CI paths to relative paths for local compatibility
36+
sed -i "s|$(pwd)/||g" lcov.info
3537
git config user.email "action@github.com"
3638
git config user.name "GitHub Action"
3739
git add lcov.info

Clarinet.toml

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ cache_dir = './.cache'
88
[[project.requirements]]
99
contract_id = 'ST3FFRX7C911PZP5RHE148YDVDD9JWVS6FZRA60VS.extension-trait'
1010

11+
[[project.requirements]]
12+
contract_id = 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.send-many'
13+
1114
[[project.requirements]]
1215
contract_id = 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait'
1316

@@ -43,138 +46,146 @@ contract_id = 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token'
4346

4447
[[project.requirements]]
4548
contract_id = 'SPDBEG5X8XD50SPM1JJH0E5CTXGDV5NJTKAKKR5V.sip013-semi-fungible-token-trait'
49+
4650
[contracts.emergency-rules]
4751
path = 'contracts/rules/emergency-rules.clar'
4852
clarity_version = 3
49-
epoch = 3.1
53+
epoch = "latest"
54+
55+
[contracts.ext-sponsored-sbtc-transfer]
56+
path = 'contracts/extensions/ext-sponsored-sbtc-transfer.clar'
57+
clarity_version = 3
58+
epoch = "latest"
59+
60+
[contracts.ext-sponsored-sbtc-transfer-many]
61+
path = 'contracts/extensions/ext-sponsored-sbtc-transfer-many.clar'
62+
clarity_version = 3
63+
epoch = "latest"
64+
65+
[contracts.ext-sponsored-sbtc-transfer_test]
66+
path = 'contracts/extensions/ext-sponsored-sbtc-transfer_test.clar'
67+
clarity_version = 3
68+
epoch = "latest"
5069

5170
[contracts.ext-delegate-stx-pox-4]
5271
path = 'contracts/extensions/ext-delegate-stx-pox-4.clar'
5372
clarity_version = 3
54-
epoch = 3.1
73+
epoch = "latest"
5574

5675
[contracts.ext-delegate-stx-pox-4_flow_test]
5776
path = 'contracts/extensions/ext-delegate-stx-pox-4_flow_test.clar'
5877
clarity_version = 3
59-
epoch = 3.1
78+
epoch = "latest"
6079

6180
[contracts.ext-sponsored-transfer]
6281
path = 'contracts/extensions/ext-sponsored-transfer.clar'
6382
clarity_version = 3
64-
epoch = 3.1
83+
epoch = "latest"
84+
85+
[contracts.ext-sponsored-send-many]
86+
path = 'contracts/extensions/ext-sponsored-send-many.clar'
87+
clarity_version = 3
88+
epoch = "latest"
6589

6690
[contracts.ext-unsafe-sip010-transfer]
6791
path = 'contracts/extensions/ext-unsafe-sip010-transfer.clar'
6892
clarity_version = 3
69-
epoch = 3.1
93+
epoch = "latest"
7094

7195
[contracts.extension-trait]
7296
path = 'contracts/extension-trait.clar'
7397
clarity_version = 3
74-
epoch = 3.1
98+
epoch = "latest"
7599

76100
[contracts.inactive-observer]
77101
path = 'contracts/admin/inactive-observer.clar'
78102
clarity_version = 3
79-
epoch = 3.1
103+
epoch = "latest"
80104

81105
[contracts.no-rules]
82106
path = 'contracts/rules/no-rules.clar'
83107
clarity_version = 3
84-
epoch = 3.1
108+
epoch = "latest"
85109

86110
[contracts.rule-set-trait]
87111
path = 'contracts/rule-set-trait.clar'
88112
clarity_version = 3
89-
epoch = 3.1
113+
epoch = "latest"
90114

91115
[contracts.smart-wallet-with-rules]
92116
path = 'contracts/smart-wallet-with-rules.clar'
93117
clarity_version = 3
94-
epoch = 3.1
118+
epoch = "latest"
95119

96120
[contracts.smart-wallet-standard]
97121
path = 'contracts/smart-wallet-standard.clar'
98122
clarity_version = 3
99-
epoch = 3.1
123+
epoch = "latest"
100124

101125
[contracts.smart-wallet-standard-2]
102126
path = 'contracts/smart-wallet-standard.clar'
103127
clarity_version = 3
104-
epoch = 3.1
128+
epoch = "latest"
105129

106130
[contracts.smart-wallet-group]
107131
path = 'contracts/smart-wallet-group.clar'
108132
clarity_version = 3
109-
epoch = 3.1
133+
epoch = "latest"
110134

111135
[contracts.smart-wallet-group_test]
112136
path = 'contracts/smart-wallet-group_test.clar'
113137
clarity_version = 3
114-
epoch = 3.1
138+
epoch = "latest"
115139

116140
[contracts.smart-wallet-standard_test]
117141
path = 'contracts/smart-wallet-standard_test.clar'
118142
clarity_version = 3
119-
epoch = 3.1
120-
143+
epoch = "latest"
121144

122145
[contracts.smart-wallet-endpoint]
123146
path = 'contracts/smart-wallet-endpoint.clar'
124147
clarity_version = 3
125-
epoch = 3.1
148+
epoch = "latest"
126149

127150
[contracts.smart-wallet-trait]
128151
path = 'contracts/smart-wallet-trait.clar'
129152
clarity_version = 3
130-
epoch = 3.1
131-
153+
epoch = "latest"
132154

133155
[contracts.smart-wallet-with-rules-trait]
134156
path = 'contracts/smart-wallet-with-rules-trait.clar'
135157
clarity_version = 3
136-
epoch = 3.1
158+
epoch = "latest"
137159

138160
[contracts.standard-rules]
139161
path = 'contracts/rules/standard-rules.clar'
140162
clarity_version = 3
141-
epoch = 3.1
163+
epoch = "latest"
142164

143165
[contracts.ext-test]
144166
path = 'contracts/tests/ext-test.clar'
145167
clarity_version = 3
146-
epoch = 3.1
147-
148-
[contracts.ext-sponsored-sbtc-transfer]
149-
path = 'contracts/extensions/ext-sponsored-sbtc-transfer.clar'
150-
clarity_version = 3
151-
epoch = 3.1
152-
153-
[contracts.ext-sponsored-sbtc-transfer_test]
154-
path = 'contracts/extensions/ext-sponsored-sbtc-transfer_test.clar'
155-
clarity_version = 3
156-
epoch = 3.1
157-
168+
epoch = "latest"
158169

159170
[contracts.csw-registry]
160171
path = 'contracts/csw-registry.clar'
161172
clarity_version = 3
162-
epoch = 3.1
173+
epoch = "latest"
163174

164175
[contracts.csw-registry_test]
165176
path = 'contracts/csw-registry_test.clar'
166177
clarity_version = 3
167-
epoch = 3.1
178+
epoch = "latest"
168179

169180
[contracts.dummy-csw]
170181
path = 'contracts/tests/dummy-csw.clar'
171182
clarity_version = 3
172-
epoch = 3.1
183+
epoch = "latest"
173184

174185
[contracts.dummy-csw-2]
175186
path = 'contracts/tests/dummy-csw.clar'
176187
clarity_version = 3
177-
epoch = 3.1
188+
epoch = "latest"
178189

179190
[repl.analysis]
180191
passes = ['check_checker']

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,11 @@ pnpm install
2626
pnpm generate
2727
pnpm test
2828
```
29+
30+
To visualize the project coverage:
31+
32+
```bash
33+
genhtml lcov.info --output-directory coverage-html --title "CSW Locker Contracts Coverage" --show-details --legend
34+
cd coverage-html/
35+
npx http-server . -p 8080
36+
```
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
;; title: ext-sbtc-transfer-many
2+
;; version: 1.0
3+
;; summary: Transfers SBTC tokens to many recipients using custom tuple format.
4+
;; description: Optimized for buffer size.
5+
6+
(define-constant ERR_TRANSFER_INDEX_PREFIX u1000)
7+
8+
(define-constant err-invalid-payload (err u500))
9+
10+
;; Uses compressed tuple format to fit more recipients within buffer limits.
11+
;;
12+
;; Max recipients:
13+
;; - 41 standard principals
14+
;; - 11 contract principals
15+
(define-private (sbtc-transfer-many-custom (recipients (list 200 {
16+
a: uint,
17+
r: principal,
18+
})))
19+
(fold sbtc-transfer-many-iter recipients (ok u0))
20+
)
21+
22+
(define-private (sbtc-transfer-many-iter
23+
(individual-transfer {
24+
a: uint,
25+
r: principal,
26+
})
27+
(result (response uint uint))
28+
)
29+
(match result
30+
index (begin
31+
(unwrap!
32+
(sbtc-transfer (get a individual-transfer) tx-sender
33+
(get r individual-transfer)
34+
)
35+
(err (+ ERR_TRANSFER_INDEX_PREFIX index))
36+
)
37+
(ok (+ index u1))
38+
)
39+
err-index (err err-index)
40+
)
41+
)
42+
43+
(define-private (sbtc-transfer
44+
(amount uint)
45+
(from principal)
46+
(to principal)
47+
)
48+
(contract-call? 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token transfer
49+
amount from to none
50+
)
51+
)
52+
53+
(define-public (call (payload (buff 2048)))
54+
(let ((details (unwrap!
55+
(from-consensus-buff? {
56+
recipients: (list
57+
200
58+
{
59+
a: uint,
60+
r: principal,
61+
}
62+
),
63+
fees: uint,
64+
}
65+
payload
66+
)
67+
err-invalid-payload
68+
)))
69+
(try! (sbtc-transfer-many-custom (get recipients details)))
70+
(match tx-sponsor?
71+
spnsr (let ((fees (get fees details)))
72+
(and (> fees u0) (try! (sbtc-transfer fees tx-sender spnsr)))
73+
)
74+
true
75+
)
76+
(ok true)
77+
)
78+
)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
;; title: ext-sbtc-transfer-many
2+
;; version: 1.0
3+
;; summary: Transfers SBTC tokens to many recipients
4+
;; description:
5+
6+
(define-constant err-invalid-payload (err u500))
7+
8+
(define-private (send-many (recipients (list 200 {
9+
ustx: uint,
10+
to: principal,
11+
})))
12+
(contract-call? 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.send-many send-many recipients)
13+
)
14+
15+
(define-public (call (payload (buff 2048)))
16+
(let ((details (unwrap!
17+
(from-consensus-buff? {
18+
recipients: (list
19+
200
20+
{
21+
ustx: uint,
22+
to: principal,
23+
}
24+
),
25+
fees: uint,
26+
}
27+
payload
28+
)
29+
err-invalid-payload
30+
)))
31+
(try! (send-many (get recipients details)))
32+
(match tx-sponsor?
33+
spnsr (try! (stx-transfer? (get fees details) tx-sender spnsr))
34+
true
35+
)
36+
(ok true)
37+
)
38+
)

contracts/smart-wallet-endpoint.clar

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@
2020
)
2121
)
2222

23+
(define-public (stx-send-many-sponsored (sm <wallet-trait>) (details {
24+
recipients: (list 11 {
25+
ustx: uint,
26+
to: principal,
27+
}),
28+
fees: uint,
29+
}))
30+
(contract-call? sm extension-call .ext-sponsored-send-many
31+
(unwrap! (to-consensus-buff? details) err-invalid-payload)
32+
)
33+
)
34+
2335
(define-public (sbtc-transfer-sponsored
2436
(sm <wallet-trait>)
2537
(details {
@@ -33,6 +45,23 @@
3345
)
3446
)
3547

48+
(define-public (sbtc-transfer-many-sponsored
49+
(sm <wallet-trait>)
50+
(details {
51+
recipients: (list 11 {
52+
;; Amount in sats.
53+
a: uint,
54+
;; Recipient address.
55+
r: principal,
56+
}),
57+
fees: uint,
58+
})
59+
)
60+
(contract-call? sm extension-call .ext-sponsored-sbtc-transfer-many
61+
(unwrap! (to-consensus-buff? details) err-invalid-payload)
62+
)
63+
)
64+
3665
(define-public (transfer-unsafe-sip-010-token
3766
(sm <wallet-trait>)
3867
(details {

0 commit comments

Comments
 (0)