Skip to content

Commit 97817af

Browse files
committed
sui fixes
1 parent 570e6bd commit 97817af

File tree

3 files changed

+82
-28
lines changed

3 files changed

+82
-28
lines changed

chain/sui/provider/ctf_provider.go

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99
"time"
1010

1111
"github.com/avast/retry-go/v4"
12+
"github.com/block-vision/sui-go-sdk/models"
1213
sui_sdk "github.com/block-vision/sui-go-sdk/sui"
14+
"github.com/go-resty/resty/v2"
1315
chain_selectors "github.com/smartcontractkit/chain-selectors"
1416
"github.com/smartcontractkit/chainlink-testing-framework/framework"
1517
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain"
@@ -135,9 +137,8 @@ func (p *CTFChainProvider) startContainer(
135137
chainID string, account sui.SuiSigner,
136138
) (string, sui_sdk.ISuiAPI) {
137139
var (
138-
attempts = uint(10)
139-
url string
140-
containerName string
140+
attempts = uint(10)
141+
url string
141142
)
142143

143144
// initialize the docker network used by CTF
@@ -171,7 +172,7 @@ func (p *CTFChainProvider) startContainer(
171172
testcontainers.CleanupContainer(p.t, output.Container)
172173

173174
return containerResult{
174-
url: output.Nodes[0].ExternalHTTPUrl + "/v1",
175+
url: output.Nodes[0].ExternalHTTPUrl,
175176
containerName: output.ContainerName,
176177
}, nil
177178
},
@@ -183,7 +184,6 @@ func (p *CTFChainProvider) startContainer(
183184
require.NoError(p.t, err)
184185

185186
url = result.url
186-
containerName = result.containerName
187187

188188
client := sui_sdk.NewSuiClient(url)
189189

@@ -198,14 +198,23 @@ func (p *CTFChainProvider) startContainer(
198198
}
199199
require.True(p.t, ready, "Sui network not ready")
200200

201-
dc, err := framework.NewDockerClient()
202-
require.NoError(p.t, err)
203-
204-
_, err = dc.ExecContainer(containerName, []string{
205-
"sui", "client", "faucet",
206-
"--address", address,
207-
})
201+
err = fundAccount(fmt.Sprintf("http://%s:%s", "127.0.0.1", "9123"), address)
208202
require.NoError(p.t, err)
209203

210204
return url, client
211205
}
206+
207+
func fundAccount(url string, address string) error {
208+
r := resty.New().SetBaseURL(url)
209+
b := &models.FaucetRequest{
210+
FixedAmountRequest: &models.FaucetFixedAmountRequest{
211+
Recipient: address,
212+
},
213+
}
214+
resp, err := r.R().SetBody(b).SetHeader("Content-Type", "application/json").Post("/gas")
215+
if err != nil {
216+
return err
217+
}
218+
framework.L.Info().Any("Resp", resp).Msg("Address is funded!")
219+
return nil
220+
}

chain/sui/signer.go

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package sui
22

33
import (
4+
"crypto/ed25519"
5+
"encoding/base64"
46
"encoding/hex"
5-
"errors"
67
"fmt"
78

8-
"github.com/block-vision/sui-go-sdk/constant"
99
"github.com/block-vision/sui-go-sdk/signer"
10+
"golang.org/x/crypto/blake2b"
1011
)
1112

1213
// TODO: Everything in this file should come from chainlink-sui when available
@@ -45,23 +46,67 @@ func NewSignerFromHexPrivateKey(hexPrivateKey string) (SuiSigner, error) {
4546
}
4647

4748
func (s *suiSigner) Sign(message []byte) ([]string, error) {
48-
if s.signer == nil {
49-
return nil, errors.New("signer is nil")
50-
}
49+
// Add intent scope for transaction data (0x00, 0x00, 0x00)
50+
intentMessage := append([]byte{0x00, 0x00, 0x00}, message...)
5151

52-
// Sign the message as a transaction message
53-
signedMsg, err := s.signer.SignMessage(string(message), constant.TransactionDataIntentScope)
54-
if err != nil {
55-
return nil, fmt.Errorf("failed to sign message: %w", err)
56-
}
52+
// Hash the message with blake2b
53+
hash := blake2b.Sum256(intentMessage)
54+
55+
// Sign the hash
56+
signature := ed25519.Sign(s.signer.PriKey, hash[:])
5757

58-
return []string{signedMsg.Signature}, nil
58+
// Get public key
59+
publicKey := s.signer.PriKey.Public().(ed25519.PublicKey)
60+
61+
// Create serialized signature: flag + signature + pubkey
62+
serializedSig := make([]byte, 1+len(signature)+len(publicKey))
63+
serializedSig[0] = 0x00 // Ed25519 flag
64+
copy(serializedSig[1:], signature)
65+
copy(serializedSig[1+len(signature):], publicKey)
66+
67+
// Encode to base64
68+
encoded := base64.StdEncoding.EncodeToString(serializedSig)
69+
70+
return []string{encoded}, nil
5971
}
6072

6173
func (s *suiSigner) GetAddress() (string, error) {
62-
if s.signer == nil {
63-
return "", errors.New("signer is nil")
74+
publicKey := s.signer.PriKey.Public().(ed25519.PublicKey)
75+
76+
// For Ed25519, the signature scheme is 0x00
77+
const signatureScheme = 0x00
78+
79+
// Create the data to hash: signature scheme byte || public key
80+
data := append([]byte{signatureScheme}, publicKey...)
81+
82+
// Hash using Blake2b-256
83+
hash := blake2b.Sum256(data)
84+
85+
// The Sui address is the hex representation of the hash
86+
return "0x" + hex.EncodeToString(hash[:]), nil
87+
}
88+
89+
// PublicKeyBytes extracts the raw 32-byte ed25519 public key from a SuiSigner.
90+
func PublicKeyBytes(s SuiSigner) ([]byte, error) {
91+
impl, ok := s.(*suiSigner)
92+
if !ok {
93+
return nil, fmt.Errorf("unsupported signer type %T", s)
94+
}
95+
priv := []byte(impl.signer.PriKey)
96+
if len(priv) != ed25519.PrivateKeySize {
97+
return nil, fmt.Errorf("unexpected ed25519 key length: %d", len(priv))
6498
}
99+
pub := make([]byte, ed25519.PublicKeySize)
100+
copy(pub, priv[32:]) // last 32 bytes are the pubkey
101+
return pub, nil
102+
}
65103

66-
return s.signer.Address, nil
104+
// PrivateKey returns the underlying ed25519.PrivateKey (64 bytes = seed||pubkey)
105+
// from a SuiSigner created in this package.
106+
func PrivateKey(s SuiSigner) (ed25519.PrivateKey, error) {
107+
impl, ok := s.(*suiSigner)
108+
if !ok {
109+
return nil, fmt.Errorf("unsupported signer type %T", s)
110+
}
111+
return impl.signer.PriKey, nil
67112
}

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313
github.com/ethereum/go-ethereum v1.15.6
1414
github.com/fbsobreira/gotron-sdk v0.0.0-20250403083053-2943ce8c759b
1515
github.com/gagliardetto/solana-go v1.12.0
16+
github.com/go-resty/resty/v2 v2.16.3
1617
github.com/google/uuid v1.6.0
1718
github.com/pelletier/go-toml/v2 v2.2.4
1819
github.com/smartcontractkit/chain-selectors v1.0.60
@@ -31,6 +32,7 @@ require (
3132
github.com/xssnick/tonutils-go v1.13.0
3233
github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6
3334
go.uber.org/zap v1.27.0
35+
golang.org/x/crypto v0.40.0
3436
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0
3537
golang.org/x/oauth2 v0.26.0
3638
google.golang.org/grpc v1.71.0
@@ -116,7 +118,6 @@ require (
116118
github.com/go-playground/locales v0.14.1 // indirect
117119
github.com/go-playground/universal-translator v0.18.1 // indirect
118120
github.com/go-playground/validator/v10 v10.25.0 // indirect
119-
github.com/go-resty/resty/v2 v2.16.3 // indirect
120121
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
121122
github.com/gofrs/flock v0.12.1 // indirect
122123
github.com/gogo/protobuf v1.3.2 // indirect
@@ -262,7 +263,6 @@ require (
262263
go.uber.org/atomic v1.11.0 // indirect
263264
go.uber.org/multierr v1.11.0 // indirect
264265
go.uber.org/ratelimit v0.3.1 // indirect
265-
golang.org/x/crypto v0.40.0 // indirect
266266
golang.org/x/net v0.42.0 // indirect
267267
golang.org/x/sync v0.16.0 // indirect
268268
golang.org/x/sys v0.34.0 // indirect

0 commit comments

Comments
 (0)