Skip to content

Commit 3cb1844

Browse files
Merge pull request #37 from everFinance/bundle
Bundle
2 parents 869b305 + df88740 commit 3cb1844

12 files changed

+666
-226
lines changed

README.md

+70-27
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,9 @@ Package for Arweave develop toolkit.
162162
- [x] GetSignatureData
163163
- [x] VerifyTransaction
164164
- [x] NewBundle
165-
- [x] GenerateIndepHash
165+
- [x] NewBundleItem
166+
- [x] SubmitItemToBundlr
167+
- [x] SubmitItemToArSeed
166168

167169
#### RSA Threshold Cryptography
168170

@@ -309,58 +311,84 @@ assert.NoError(t, uploader.Once())
309311
### About Arweave Bundles
310312
1. `goar` implemented creating,editing,reading and verifying bundles tx
311313
2. This is the [ANS-104](https://github.com/joshbenaron/arweave-standards/blob/ans104/ans/ANS-104.md) standard protocol and refers to the [arbundles](https://github.com/Bundler-Network/arbundles) js-lib implement
312-
3. more example can be viewed in path `./example/bundle_test.go`
313314

314-
#### CreateBundle
315+
#### Create Bundle Item
315316
```go
316-
w, err := goar.NewWalletFromPath(privateKey, arNode)
317-
if err != nil {
318-
panic(err)
319-
}
317+
signer, err := goar.NewSignerFromPath("./testKey.json") // rsa signer
318+
// or
319+
signer, err := goether.NewSigner("0x.....") // ecdsa signer
320320

321321
// Create Item
322-
data := []byte("upload update...")
323-
signatureType := 1 // currently only supply type 1
322+
data := []byte("aa bb cc dd")
324323
target := "" // option
325324
anchor := "" // option
326-
tags := []types.Tags{}{} // bundle item tags
327-
item01, err := w.CreateAndSignBundleItem(data, 1, target, anchor, tags)
325+
tags := []types.Tags{}{} // option bundle item tags
326+
item01, err := itemSigner.CreateAndSignItem(data, target, anchor, tags)
328327
// Same as create item
329328
item02
330329
item03
331330
....
332331

333-
items := []types.BundleItem{item01, item02, item03 ...}
332+
```
333+
#### assemble bundle and send to arweave network
334+
You can send items directly to the arweave network
335+
```go
334336

337+
items := []types.BundleItem{item01, item02, item03 ...}
335338
bundle, err := utils.NewBundle(items...)
336339

340+
w, err := goar.NewWalletFromPath("./key.json", arNode)
341+
342+
arTxTags := []types.Tags{}{} // option
343+
tx, err := w.SendBundleTx(bd.BundleBinary, arTxtags)
344+
337345
```
338346

339-
#### Send Item to Bundler
340-
Bundler network provides guaranteed data seeding and instant data accessibility
347+
#### Send Item to [Arseeding](https://github.com/everFinance/arseeding) gateway
348+
Arseeding provides guaranteed data seeding and instant data accessibility
341349
```go
342-
resp, err := w.Client.BatchSendItemToBundler(items,"") // The second parameter is the bundler gateway url,"" means use default url
350+
arseedUrl := "https://seed.everpay.io"
351+
currency := "USDC" // used for payment fee currency
352+
resp, err := utils.SubmitItemToArSeed(item01,currency,arseedUrl)
343353
```
344354

345-
#### Send Bundle Tx
355+
#### Send Item to Bundler gateway
356+
Bundler provides guaranteed data seeding and instant data accessibility
346357
```go
347-
tx, err := w.SendBundleTx(bd.BundleBinary, arTxtags)
358+
bundlrUrl := "https://node1.bundlr.network"
359+
resp, err := utils.SubmitItemToBundlr(item01, bundlrUrl)
348360
```
349361

350-
#### Get Bundle and Verify
362+
#### Verify Bundle Items
351363
```go
352-
id := "lt24bnUGms5XLZeVamSPHePl4M2ClpLQyRxZI7weH1k"
353-
bundle, err := cli.GetBundle(id)
354364

355365
// verify
356366
for _, item := range bundle.Items {
357367
err = utils.VerifyBundleItem(item)
358368
assert.NoError(t, err)
359369
}
360370
```
371+
check [bundle example](./example/bundle_test.go)
361372

362-
### notice
363-
if you call `w.Client.BatchSendItemToBundler(items,"")`
373+
#### About Arseeding
374+
if you can `utils.SubmitItemToArseed(item,currency,arseedUrl)`
375+
and you will get the following return response
376+
```go
377+
{
378+
"ItemId": "5rEb7c6OjMQIYjl6P7AJIb4bB9CLMBSxhZ9N7BVbRCk",
379+
"bundler": "Fkj5J8CDLC9Jif4CzgtbiXJBnwXLSrp5AaIllleH_yY",
380+
"currency": "USDT",
381+
"decimals": 6,
382+
"fee": "701",
383+
"paymentExpiredTime": 1656044994,
384+
"expectedBlock": 960751
385+
}
386+
```
387+
After you transfer 0.000701 USDT to bundler using everpay, arseeding will upload the item to arweave.
388+
For more usage, jump to [docs](https://github.com/everFinance/arseeding/blob/main/README.md)
389+
390+
#### About Bundlr
391+
if you call `utils.SubmitItemToBundlr(item,bundlrUrl)`
364392
and return `panic: send to bundler request failed; http code: 402`
365393
means that you have to pay ar to the bundler service address
366394
must use item signature address to transfer funds
@@ -371,13 +399,28 @@ curl --location --request GET 'https://node1.bundlr.network/info'
371399

372400
response:
373401
{
374-
"uptime": 275690.552536824,
375-
"address": "OXcT1sVRSA5eGwt2k6Yuz8-3e3g9WJi5uSE99CWqsBs",
376-
"gateway": "arweave.net"
402+
"version": "0.2.0",
403+
"addresses": {
404+
"arweave": "OXcT1sVRSA5eGwt2k6Yuz8-3e3g9WJi5uSE99CWqsBs",
405+
"ethereum": "0xb4DE0833771eae55040b698aF5eB06d59E142C82",
406+
"matic": "0xb4DE0833771eae55040b698aF5eB06d59E142C82",
407+
"bnb": "0xb4DE0833771eae55040b698aF5eB06d59E142C82",
408+
"avalanche": "0xb4DE0833771eae55040b698aF5eB06d59E142C82",
409+
"solana": "DHyDV2ZjN3rB6qNGXS48dP5onfbZd3fAEz6C5HJwSqRD",
410+
"arbitrum": "0xb4DE0833771eae55040b698aF5eB06d59E142C82",
411+
"boba-eth": "0xb4DE0833771eae55040b698aF5eB06d59E142C82",
412+
"boba": "0xb4DE0833771eae55040b698aF5eB06d59E142C82",
413+
"chainlink": "0xb4DE0833771eae55040b698aF5eB06d59E142C82",
414+
"kyve": "0xb4DE0833771eae55040b698aF5eB06d59E142C82",
415+
"fantom": "0xb4DE0833771eae55040b698aF5eB06d59E142C82",
416+
"near": "bundlr1.near",
417+
"algorand": "DL7ZTTQMTFNXRF3367OTSNAZ3L2X676OJ4GGB3DXMUJ37CCKJ5RJMEO6RI"
418+
},
419+
"gateway": "arweave.net"
377420
}
378421
```
379-
This "address" is the bundler service receive ar address.
380-
You need to transfer a certain amount of ar to this address
422+
This "addresses" are the bundler service receive address.
423+
You need to transfer a certain amount of token to this address
381424
and wait for 25 blocks to confirm the transaction before you can use the bundler service.
382425

383426
You can also use the following api to query the balance in the bundler service.

bundleItem.go

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package goar
2+
3+
import (
4+
"crypto/sha256"
5+
"errors"
6+
"github.com/everFinance/goar/types"
7+
"github.com/everFinance/goar/utils"
8+
"github.com/everFinance/goether"
9+
)
10+
11+
type ItemSigner struct {
12+
signType int
13+
signer interface{}
14+
owner string // only rsa has owner
15+
signerAddr string
16+
}
17+
18+
func NewItemSigner(signer interface{}) (*ItemSigner, error) {
19+
signType, signerAddr, owner, err := reflectSigner(signer)
20+
if err != nil {
21+
return nil, err
22+
}
23+
return &ItemSigner{
24+
signType: signType,
25+
signer: signer,
26+
owner: owner,
27+
signerAddr: signerAddr,
28+
}, nil
29+
}
30+
31+
func (i *ItemSigner) CreateAndSignItem(data []byte, target string, anchor string, tags []types.Tag) (types.BundleItem, error) {
32+
bundleItem, err := utils.NewBundleItem(i.owner, i.signType, target, anchor, data, tags)
33+
if err != nil {
34+
return types.BundleItem{}, err
35+
}
36+
// sign
37+
if err := SignBundleItem(i.signType, i.signer, bundleItem); err != nil {
38+
return types.BundleItem{}, err
39+
}
40+
if err := utils.GenerateItemBinary(bundleItem); err != nil {
41+
return types.BundleItem{}, err
42+
}
43+
return *bundleItem, nil
44+
}
45+
46+
func reflectSigner(signer interface{}) (signType int, signerAddr, owner string, err error) {
47+
if s, ok := signer.(*Signer); ok {
48+
signType = types.ArweaveSignType
49+
signerAddr = s.Address
50+
owner = s.Owner()
51+
return
52+
}
53+
if s, ok := signer.(*goether.Signer); ok {
54+
signType = types.EthereumSignType
55+
signerAddr = s.Address.String()
56+
owner = utils.Base64Encode(s.GetPublicKey())
57+
return
58+
}
59+
err = errors.New("not support this signer")
60+
return
61+
}
62+
63+
func SignBundleItem(signatureType int, signer interface{}, item *types.BundleItem) error {
64+
signMsg, err := utils.BundleItemSignData(*item)
65+
if err != nil {
66+
return err
67+
}
68+
var sigData []byte
69+
switch signatureType {
70+
case types.ArweaveSignType:
71+
arSigner, ok := signer.(*Signer)
72+
if !ok {
73+
return errors.New("signer must be goar signer")
74+
}
75+
sigData, err = utils.Sign(signMsg, arSigner.PrvKey)
76+
if err != nil {
77+
return err
78+
}
79+
80+
case types.EthereumSignType:
81+
ethSigner, ok := signer.(*goether.Signer)
82+
if !ok {
83+
return errors.New("signer not goether signer")
84+
}
85+
sigData, err = ethSigner.SignMsg(signMsg)
86+
if err != nil {
87+
return err
88+
}
89+
default:
90+
// todo come soon supprot ed25519
91+
return errors.New("not supprot this signType")
92+
}
93+
id := sha256.Sum256(sigData)
94+
item.Id = utils.Base64Encode(id[:])
95+
item.Signature = utils.Base64Encode(sigData)
96+
return nil
97+
}

client.go

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"path"
1414
"strconv"
1515
"strings"
16+
"time"
1617

1718
"github.com/everFinance/goar/types"
1819
"github.com/everFinance/goar/utils"
@@ -54,6 +55,10 @@ func (c *Client) SetTempConnUrl(url string) {
5455
c.url = url
5556
}
5657

58+
func (c *Client) SetTimeout(timeout time.Duration) {
59+
c.client.Timeout = timeout
60+
}
61+
5762
func (c *Client) GetInfo() (info *types.NetworkInfo, err error) {
5863
body, code, err := c.httpGet("info")
5964
if err != nil {

client_bundle.go

-66
This file was deleted.

client_test.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ import (
66
"testing"
77
)
88

9-
// import (
10-
// "fmt"
11-
// "testing"
12-
139
// func TestGetTransactionByID(t *testing.T) {
1410
// client := NewClient("https://arweave.net")
1511
// fmt.Println(client.GetTransactionByID("FgcKlptyDXSgEonYfy5cNBimq7GJ4h8h6L6pxuuYOBc"))
@@ -265,3 +261,19 @@ func TestNewClient(t *testing.T) {
265261
assert.NoError(t, err)
266262
t.Log("pending tx number:", len(res))
267263
}
264+
265+
func TestNewTempConn(t *testing.T) {
266+
c := NewClient("https://arweave.net")
267+
peers, err := c.GetPeers()
268+
assert.NoError(t, err)
269+
pNode := NewTempConn()
270+
for _, peer := range peers {
271+
pNode.SetTempConnUrl("http://" + peer)
272+
offset, err := pNode.getTransactionOffset("pEYudvF0HjIU-2vKdhNZ9Dgr_bueucXaeRrbPhI90ew")
273+
if err != nil {
274+
t.Log("err", err, "perr", peer)
275+
continue
276+
}
277+
t.Logf("offset: %s, peer: %s", offset.Offset, peer)
278+
}
279+
}

0 commit comments

Comments
 (0)