main
go 86 lines 2.1 KB
Raw
1 package x402
2
3 import (
4 "errors"
5 "fmt"
6 "net/http"
7 "strings"
8
9 facilitatorapi "github.com/gosuda/x402-facilitator/api"
10 facilitatorcore "github.com/gosuda/x402-facilitator/facilitator"
11 suischeme "github.com/gosuda/x402-facilitator/scheme/sui"
12
13 "github.com/gosuda/portal-tunnel/v2/types"
14 )
15
16 const (
17 MainnetNetwork = "sui:mainnet"
18 TestnetNetwork = "sui:testnet"
19
20 defaultMaxTimeoutSeconds = 60
21 )
22
23 var networkDisplayNames = map[string]string{
24 MainnetNetwork: "Sui Mainnet",
25 TestnetNetwork: "Sui Testnet",
26 }
27
28 func Network(testnet bool) string {
29 if testnet {
30 return TestnetNetwork
31 }
32 return MainnetNetwork
33 }
34
35 func NetworkDisplayName(network string) string {
36 return networkDisplayNames[strings.TrimSpace(strings.ToLower(network))]
37 }
38
39 type FacilitatorConfig struct {
40 Testnet bool
41 }
42
43 func MountFacilitator(mux *http.ServeMux, cfg FacilitatorConfig) error {
44 if mux == nil {
45 return errors.New("x402 facilitator requires an api mux")
46 }
47 facilitator, err := newUSDCFacilitator(Network(cfg.Testnet), "")
48 if err != nil {
49 return fmt.Errorf("create sui x402 facilitator: %w", err)
50 }
51 mux.Handle(types.PathX402Facilitator+"/", http.StripPrefix(types.PathX402Facilitator, facilitatorapi.NewServer(facilitator)))
52 return nil
53 }
54
55 func usdcAsset(network string) (string, error) {
56 network = strings.ToLower(strings.TrimSpace(network))
57 asset, ok := suischeme.GetGaslessStablecoinType(network, "USDC")
58 if !ok {
59 return "", fmt.Errorf("USDC is not gasless stablecoin allowlisted on %s", network)
60 }
61 return asset, nil
62 }
63
64 func newUSDCFacilitator(network, asset string, endpoints ...string) (facilitatorcore.Facilitator, error) {
65 network = strings.ToLower(strings.TrimSpace(network))
66 if network == "" {
67 network = MainnetNetwork
68 }
69 if asset == "" {
70 var err error
71 asset, err = usdcAsset(network)
72 if err != nil {
73 return nil, err
74 }
75 }
76 url := ""
77 for _, endpoint := range endpoints {
78 if endpoint = strings.TrimSpace(endpoint); endpoint != "" {
79 url = endpoint
80 break
81 }
82 }
83 return facilitatorcore.NewSuiFacilitatorWithOptions(network, url, "", facilitatorcore.SuiFacilitatorOptions{
84 GaslessStablecoinTypes: []string{asset},
85 })
86 }